/******************************************************************************
 * * mmi_modem_adaptor_sim.c - implementation of mmi-modem adaptor, sim sub-module
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "lv_watch.h"

#if USE_LV_WATCH_MODEM_ADAPTOR
#include "mmi_modem_adaptor_sms.h"

Modem_SMS_Mng_t               g_ModemSmsMng;
MMI_Modem_Read_Sms_Info_Cnf_t * gp_ModemSms_ReadSmsInfoCnf;
const char g_ChinaMobile_Mnc[6][3] = {"00","02","04","07","08","13"};
const char g_ChinaUnicom_Mnc[4][3] = {"01","06","09","10"};
const char g_ChinaTelecom_Mnc[4][3] = {"03","05","11","12"};
const char g_China_Mcc[4] = "460";
const char g_China_KtSms[4][8] = {"KTVOLTE","DGVOLTE","KTVOLTE","KTGQTH"};
const char g_China_KtNum[3][6] = {"10086","10010","10001"};

#define MESSAGE_APP_DEMO 1
#define CHINA_UNICOM_TELECOM 0

/******************************************************************************
 *
 *         Functions
 *
 *******************************************************************************/

#if MESSAGE_APP_DEMO
static void MMI_ModemAdp_Sms_Send_Result_Ind(watch_app_adp_sms_send_result_type_t result)
{
    printf("##interface## %s:result is %d!\n", __FUNCTION__, result);
    if(APP_SMS_SEND_SUCCESS != result) {
        g_ModemSmsMng.VolteOpenSmsFlg = 0;
    } else {
        if(g_ModemSmsMng.ChinaMobileFlg) {
            MMI_ModemAdp_Check_China_Operator_t *Operator_sec = (MMI_ModemAdp_Check_China_Operator_t *)Hal_Mem_Alloc(sizeof(MMI_ModemAdp_Check_China_Operator_t));
            Hal_Mem_Set(Operator_sec,0,sizeof(MMI_ModemAdp_Check_China_Operator_t));
            Operator_sec->send_flg = 1;
            g_ModemSmsMng.ChinaMobileFlg = 0;
            MMI_ModemAdp_Check_China_Operator(Operator_sec);
            if(NULL != Operator_sec->data) {
                printf("##interface## %s:sec number is %s,sec data is %s\n", __FUNCTION__,Operator_sec->number,Operator_sec->data);
                app_adaptor_sms_send_req(Operator_sec->number, Operator_sec->data, 6, NULL, MMI_ModemAdp_Sms_Send_Result_Ind);
            }
            Hal_Mem_Free(Operator_sec);
        }
    }
}
/**
 * demo for message app
 * param (in) sms_info: app_adp_new_sms_info_ind_t *
 * return  void
 */
void MMI_Modem_New_Sms_Ind(app_adp_new_sms_info_ind_t * sms_info)
{
    printf("%s\n", __FUNCTION__);
    char *number = NULL;
    char *data = NULL;
#if USE_LV_WATCH_DUMMY_SMS
#if CHINA_UNICOM_TELECOM
    char *data_temp = sms_info->data;//dummy test data
    char sms[] = "：确认“Y”开通";//dummy test data
#endif
#endif
    uint8_t send_flg = 0;
    app_adaptor_new_message_info_t * msg_info = NULL;
    msg_info = (app_adaptor_new_message_info_t *)lv_mem_alloc(sizeof(app_adaptor_new_message_info_t));
    _lv_memset_00(msg_info, sizeof(app_adaptor_new_message_info_t));

    if(1 == g_ModemSmsMng.VolteOpenSmsFlg) {
#if USE_LV_WATCH_DUMMY_SMS
#if CHINA_UNICOM_TELECOM
        sms_info->data = sms;//dummy test data
#endif
#endif
        printf("%s:number is %s\n", __FUNCTION__,sms_info->number);
        printf("%s:data is %s\n", __FUNCTION__,sms_info->data);
        if(NULL != strstr(sms_info->number,g_China_KtNum[0])) {
            if(NULL != strstr(sms_info->data,"Y")) {
                send_flg = 1;
            } else if(NULL != strstr(sms_info->data,"“是”")) {
                send_flg = 2;
            }
        } else if(0 == strcmp(sms_info->number,g_China_KtNum[1])) {
            if(NULL != strstr(sms_info->data,"Y")) {
                send_flg = 1;
            }
        } else if(0 == strcmp(sms_info->number,g_China_KtNum[2])) {
            if(NULL != strstr(sms_info->data,"Y")) {
                send_flg = 1;
            }
        } else {
            printf("%s:number is not China Mobile&Unicom&Telecom\n", __FUNCTION__);
        }
    }
    if(1 == send_flg) {
        number = lv_strdup(sms_info->number);
        data = lv_strdup("Y");
        g_ModemSmsMng.VolteOpenSmsFlg = 0;
        printf("%s:send number is %s,send data is %s,send_flg is %d\n", __FUNCTION__,number,data,send_flg);
        app_adaptor_sms_send_req(number, data, 1, NULL, MMI_ModemAdp_Sms_Send_Result_Ind);
    } else if(2 == send_flg) {
        number = lv_strdup(sms_info->number);
        data = lv_strdup((const char*)lang_get_chinese_text(WATCH_TEXT_ID_YES));
        g_ModemSmsMng.VolteOpenSmsFlg = 0;
        printf("%s:send number is %s,send data is %s,send_flg is %d\n", __FUNCTION__,number,data,send_flg);
        app_adaptor_sms_send_req(number, data, strlen(data), NULL, MMI_ModemAdp_Sms_Send_Result_Ind);
    }
#if USE_LV_WATCH_DUMMY_SMS
#if CHINA_UNICOM_TELECOM
    sms_info->data = data_temp;//dummy test data
#endif
#endif
    msg_info->msg_source = APP_ADP_MSG_SOURCE_SMS;
    msg_info->msg_index = rand();
    msg_info->name = (char *)lv_mem_alloc(sms_info->number_len + 1);
    _lv_memset_00(msg_info->name, sms_info->number_len + 1);
    memcpy(msg_info->name, sms_info->number, sms_info->number_len);
    msg_info->data = (char *)lv_mem_alloc(sms_info->data_len + 1);
    _lv_memset_00(msg_info->data, sms_info->data_len + 1);
    memcpy(msg_info->data, sms_info->data, sms_info->data_len);

    app_adaptor_update_message_info_req(msg_info);

    if(sms_info->number) {
        lv_mem_free(sms_info->number);
        sms_info->number = NULL;
    }
    if(sms_info->time) {
        lv_mem_free(sms_info->time);
        sms_info->time = NULL;
    }
    if(sms_info->data) {
        lv_mem_free(sms_info->data);
        sms_info->data = NULL;
    }
    if(sms_info) {
        lv_mem_free(sms_info);
        sms_info = NULL;
    }
}
#endif

/**
 * initiate mmi-modem adaptor module
 * param (in) void:
 * return  void
 */
VOID MMI_ModemAdp_Sms_Init_Req()
{
    uint8_t i = 0;

    printf("##interface## %s\n", __FUNCTION__);
    g_ModemSmsMng.SmsStatus[0]           = MODEM_SMS_IDLE;
    g_ModemSmsMng.SmsStatus[1]           = MODEM_SMS_IDLE;
    g_ModemSmsMng.DeliverStatusReport[0] = FALSE;
    g_ModemSmsMng.DeliverStatusReport[1] = FALSE;

    g_ModemSmsMng.WriteToSim     = FALSE;
    g_ModemSmsMng.pSendSms_Pdu   = NULL;
    g_ModemSmsMng.SendSms_Result = MMI_MODEM_SMS_FAIL;

    g_ModemSmsMng.pSendSms_Smsc[MMI_MODEM_SIM_1] = NULL;
    g_ModemSmsMng.pSendSms_Smsc[MMI_MODEM_SIM_2] = NULL;

    g_ModemSmsMng.NewSmsInfoIndFunc = NULL;
    g_ModemSmsMng.New8bitSmsInfoIndFunc = NULL;
    g_ModemSmsMng.SmsSendResultIndFunc = NULL;
    g_ModemSmsMng.decode_type = APP_SMS_CODE_TYPE_UTF_8;

    g_ModemSmsMng.MsmsValid = false;
    g_ModemSmsMng.IEId = MODEM_SMS_IEID_INVALID;
    g_ModemSmsMng.SegPduId = 0;
    g_ModemSmsMng.SegPduTotalLen = 0;
    g_ModemSmsMng.SegPduTotalCnt = 0;
    g_ModemSmsMng.SegPduRcvCnt = 0;
    for(i = 0; i < 16; i++) {
        g_ModemSmsMng.pSegPdu[i] = NULL;
        g_ModemSmsMng.SegPduLen[i] = 0;
    }

    g_ModemSmsMng.RefNum = 0;
    g_ModemSmsMng.MoSmsSegNum = 0;

#if MESSAGE_APP_DEMO
    app_adaptor_new_sms_info_ind_bind(MMI_Modem_New_Sms_Ind, APP_SMS_CODE_TYPE_UTF_8);
#endif
}

/******************************************************************************
 *
 *         MMI -> Modem Adaptor
 *
 *******************************************************************************/

/**
 * This is used to send SMS to operator to open VOLTE
 * param (in) SimId：MMI_MODEM_SIM_ID
 * return void
 */
void MMI_ModemAdp_Open_Volte_Req(MMI_MODEM_SIM_ID SimId)
{
    MMI_Modemadp_Open_Volte_Req_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg =
        (MMI_Modemadp_Open_Volte_Req_t *)Hal_Mem_Alloc(sizeof(
                    MMI_Modemadp_Open_Volte_Req_t));

    pMsg->SimId = SimId;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_OPEN_VOLTE_REQ,
                      (UI_Inter_Msg_t *)pMsg);
}

/**
 * send new sms req
 * param (in) pSendSms: MMI_Modem_Send_Sms_Req_t
 * return  void
 */
VOID MMI_Modem_Send_Sms_Req(MMI_Modem_Send_Sms_Req_t * pSendSms)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_SEND_SMS_REQ,
                      (UI_Inter_Msg_t *)pSendSms);
}

/**
 * delete sms req
 * param (in) pDeleteSms: MMI_Modem_Delete_Sms_Req_t
 * return  void
 */
VOID MMI_Modem_Delete_Sms_Req(MMI_Modem_Delete_Sms_Req_t * pDeleteSms)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_DEL_SMS_REQ,
                      (UI_Inter_Msg_t *)pDeleteSms);
}

/**
 * read sms info req
 * param (in) SmsBox: MMI_MODEM_SMS_OF_BOX
 * return  void
 */
VOID MMI_Modem_Read_Sms_Info_Req(MMI_MODEM_SMS_OF_BOX SmsBox)
{
    MMI_Modemadp_Read_Sms_Info_t * pMsg;

    pMsg =
        (MMI_Modemadp_Read_Sms_Info_t *)Hal_Mem_Alloc(sizeof(MMI_Modemadp_Read_Sms_Info_t));

    printf("##interface## %s\n", __FUNCTION__);
    pMsg->SmsBox = SmsBox;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_READ_SMS_INFO_REQ,
                      (UI_Inter_Msg_t *)pMsg);
}

/**
 * read sms detail on sim req
 * param (in) pReadSmsReq: MMI_Modem_Read_Sms_Detail_On_Sim_Req_t
 * return  void
 */
VOID MMI_Modem_Read_Sms_Detail_On_Sim_Req(MMI_Modem_Read_Sms_Detail_On_Sim_Req_t * pReadSmsReq)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_READ_SMS_DETAIL_ON_SIM_REQ,
                      (UI_Inter_Msg_t *)pReadSmsReq);
}

/**
 * get sms centre number req
 * param (in) SimId: MMI_MODEM_SIM_ID
 * return  void
 */
VOID MMI_Modem_Get_Smsc_Req(MMI_MODEM_SIM_ID SimId)
{
    MMI_Modemadp_Sms_Get_Smsc_Req_t * pMsg;

    printf("##interface## %s\n", __FUNCTION__);
    pMsg =
        (MMI_Modemadp_Sms_Get_Smsc_Req_t *)Hal_Mem_Alloc(sizeof(
                    MMI_Modemadp_Sms_Get_Smsc_Req_t));

    pMsg->SimId = SimId;
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_GET_SMSC_REQ, (UI_Inter_Msg_t *)pMsg);
}

/**
 * set sms centre number req
 * param (in) pSetSmscReq: MMI_Modem_Set_Smsc_Req_t
 * return  void
 */
VOID MMI_Modem_Set_Smsc_Req(MMI_Modem_Set_Smsc_Req_t * pSetSmscReq)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, MMI_MODEMADP_SET_SMSC_REQ,
                      (UI_Inter_Msg_t *)pSetSmscReq);
}

/**
 * set delivery report flg req
 * param (in) pSetDeliveryRep: MMI_Modem_Set_Delivery_Req_t
 * return  void
 */
VOID MMI_Modem_Set_Delivery_Rep_Req(MMI_Modem_Set_Delivery_Req_t * pSetDeliveryRep)
{
    printf("##interface## %s\n", __FUNCTION__);
    if(MMI_MODEM_ENABLE == pSetDeliveryRep->DeliveryRepFlg) {
        g_ModemSmsMng.DeliverStatusReport[pSetDeliveryRep->SimId] = TRUE;
    } else {
        g_ModemSmsMng.DeliverStatusReport[pSetDeliveryRep->SimId] = FALSE;
    }

    MMI_Modem_Set_Delivery_Rep_Cnf(MMI_MODEM_SMS_SUCCESS);

    // free the caller memory
    Hal_Mem_Free(pSetDeliveryRep);
}

/******************************************************************************
 *
 *         RIL -> Modem Adaptor
 *
 *******************************************************************************/

/**
 * RIL_MSG_RESPONSE_SEND_SMS
 * param       RIL_MSG_RESPONSE_SEND_SMS pSendSmsRes
 * return  void
 */
VOID Ril_MSG_Response_Send_Sms(RIL_MSG_RESPONSE_SEND_SMS * pSendSmsRes)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_SEND_SMS,
                      (UI_Inter_Msg_t *)pSendSmsRes);
}

/**
 * RIL_MSG_RESPONSE_WRITE_SMS_TO_SIM
 * param       RIL_MSG_RESPONSE_WRITE_SMS_TO_SIM pWriteSmsRes
 * return  void
 */
VOID Ril_MSG_Response_Write_Sms_to_Sim(RIL_MSG_RESPONSE_WRITE_SMS_TO_SIM * pWriteSmsRes)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_WRITE_SMS_TO_SIM,
                      (UI_Inter_Msg_t *)pWriteSmsRes);
}

/**
 * RIL_MSG_RESPONSE_READ_SMS_INFO_FROM_SIM
 * param       RIL_MSG_RESPONSE_READ_SMS_INFO_FROM_SIM pReadSmsRes
 * return  void
 */
VOID Ril_MSG_Response_Read_Sms_Info_From_Sim(RIL_MSG_RESPONSE_READ_SMS_INFO_FROM_SIM * pReadSmsRes)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_READ_SMS_INFO_FROM_SIM,
                      (UI_Inter_Msg_t *)pReadSmsRes);
}

/**
 * RIL_MSG_RESPONSE_READ_SMS_FROM_SIM
 * param       RIL_MSG_RESPONSE_READ_SMS_FROM_SIM pReadSingleSmsRes
 * return  void
 */
VOID Ril_MSG_Response_Read_Single_Sms_From_Sim(RIL_MSG_RESPONSE_READ_SMS_FROM_SIM * pReadSingleSmsRes)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_READ_SINGLE_SMS_FROM_SIM,
                      (UI_Inter_Msg_t *)pReadSingleSmsRes);
}

/**
 * RIL_MSG_RESPONSE_GET_SMSC_ADDRESS
 * param       RIL_MSG_RESPONSE_GET_SMSC_ADDRESS pGetSmscAddr
 * return  void
 */
VOID Ril_MSG_Response_Get_Smsc_Addr(RIL_MSG_RESPONSE_GET_SMSC_ADDRESS * pGetSmscAddr)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_GET_SMSC_ADDR,
                      (UI_Inter_Msg_t *)pGetSmscAddr);
}

/**
 * RIL_MSG_RESPONSE_NEW_SMS_ON_SIM
 * param       RIL_MSG_RESPONSE_NEW_SMS_ON_SIM pNewSmsOnSim
 * return  void
 */
VOID Ril_MSG_Response_New_Sms_On_Sim(RIL_MSG_RESPONSE_NEW_SMS_ON_SIM * pNewSmsOnSim)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_NEW_SMS_ON_SIM,
                      (UI_Inter_Msg_t *)pNewSmsOnSim);
}

/**
 * RIL_MSG_RESPONSE_SMS_STATUS_REP
 * param       RIL_MSG_RESPONSE_SMS_STATUS_REP pSmsStsRep
 * return  void
 */
VOID Ril_MSG_Response_Sms_Status_Rep(RIL_MSG_RESPONSE_SMS_STATUS_REP * pSmsStsRep)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_SMS_STATUS_REP,
                      (UI_Inter_Msg_t *)pSmsStsRep);
}

/**
 * RIL_MSG_RESPONSE_SMS_STORAGE_STATUS
 * param       RIL_MSG_RESPONSE_SMS_STORAGE_STATUS pSmsStorageSts
 * return  void
 */
VOID Ril_MSG_Response_Sms_Storage_Status(RIL_MSG_RESPONSE_SMS_STORAGE_STATUS * pSmsStorageSts)
{
    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_SMS_STORAGE_STATUS,
                      (UI_Inter_Msg_t *)pSmsStorageSts);
}

/******************************************************************************
 *
 *         Message Handler of MMI -> Modem Adaptor
 *
 *******************************************************************************/
VOID MMI_ModemAdp_Check_China_Operator(MMI_ModemAdp_Check_China_Operator_t *Operator)
{
    UINT8                    i                     = 0;
    if(0 == strncmp(g_ModemSimMng.RegHomePlmn[Operator->SimId].regMcc,g_China_Mcc,3)) {
        printf("##interface## %s:regMnc is %s\n", __FUNCTION__,g_ModemSimMng.RegHomePlmn[Operator->SimId].regMnc);
        for(i = 0;i < 6;i++)
        {
            if(0 == strncmp(g_ModemSimMng.RegHomePlmn[Operator->SimId].regMnc,g_ChinaMobile_Mnc[i],2)) {
                Operator->data = Hal_Mem_Alloc(8);
                Hal_Mem_Set(Operator->data,0,8);
                if(Operator->send_flg) {
                    Hal_Mem_Copy(Operator->data,g_China_KtSms[3],6);
                } else {
                    Hal_Mem_Copy(Operator->data,g_China_KtSms[0],7);
                }
                Operator->number = Hal_Mem_Alloc(6);
                Hal_Mem_Set(Operator->number,0,6);
                Hal_Mem_Copy(Operator->number,g_China_KtNum[0],5);
                printf("##interface## %s:it is China Mobile!\n", __FUNCTION__);
                break;
            }
        }
        if(NULL == Operator->data) {
            for(i = 0;i < 4;i++)
            {
                if(0 == strncmp(g_ModemSimMng.RegHomePlmn[Operator->SimId].regMnc,g_ChinaUnicom_Mnc[i],2)) {
                    Operator->data = Hal_Mem_Alloc(8);
                    Hal_Mem_Set(Operator->data,0,8);
                    Hal_Mem_Copy(Operator->data,g_China_KtSms[1],7);
                    Operator->number = Hal_Mem_Alloc(6);
                    Hal_Mem_Set(Operator->number,0,6);
                    Hal_Mem_Copy(Operator->number,g_China_KtNum[1],5);
                    printf("##interface## %s:it is China Unicom!\n", __FUNCTION__);
                    break;
                }
            }
        }
        if(NULL == Operator->data) {
            for(i = 0;i < 4;i++)
            {
                if(0 == strncmp(g_ModemSimMng.RegHomePlmn[Operator->SimId].regMnc,g_ChinaTelecom_Mnc[i],2)) {
                    Operator->data = Hal_Mem_Alloc(8);
                    Hal_Mem_Set(Operator->data,0,8);
                    Hal_Mem_Copy(Operator->data,g_China_KtSms[2],7);
                    Operator->number = Hal_Mem_Alloc(6);
                    Hal_Mem_Set(Operator->number,0,6);
                    Hal_Mem_Copy(Operator->number,g_China_KtNum[2],5);
                    printf("##interface## %s:it is China Telecom!\n", __FUNCTION__);
                    break;
                }
            }
        }
    } else {
        printf("##interface## %s:It is not China operator! and regMcc is %s,g_China_Mcc is %s\n", __FUNCTION__,g_ModemSimMng.RegHomePlmn[Operator->SimId].regMcc,g_China_Mcc);
    }
}

/**
 * Handler of MMI_MODEMADP_OPEN_VOLTE_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Open_Volte_Req_Handler(UI_Inter_Msg_t * Msg)
{
    printf("##interface## %s\n", __FUNCTION__);
    MMI_Modemadp_Open_Volte_Req_t   *    pOpenVolte = (MMI_Modemadp_Open_Volte_Req_t *)Msg;

    MMI_ModemAdp_Check_China_Operator_t *Operator = (MMI_ModemAdp_Check_China_Operator_t *)Hal_Mem_Alloc(sizeof(MMI_ModemAdp_Check_China_Operator_t));
    Hal_Mem_Set(Operator,0,sizeof(MMI_ModemAdp_Check_China_Operator_t));
    Operator->SimId = pOpenVolte->SimId;

    MMI_ModemAdp_Check_China_Operator(Operator);

    if(NULL != Operator->data) {
        printf("##interface## %s:number is %s,data is %s\n", __FUNCTION__,Operator->number,Operator->data);
        g_ModemSmsMng.VolteOpenSmsFlg = 1;
        if(0 == strcmp(Operator->number,g_China_KtNum[0])) {
            g_ModemSmsMng.ChinaMobileFlg = 1;
        }
        app_adaptor_sms_send_req(Operator->number, Operator->data, 7, NULL, MMI_ModemAdp_Sms_Send_Result_Ind);
    }
    Hal_Mem_Free(Operator);
}

/**
 * Handler of MMI_MODEMADP_SEND_SMS_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Sms_Send_Sms_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modem_Send_Sms_Req_t     *    pSendSms;
    RIL_MSG_REQUEST_SEND_SMS     *    pSendSmsReq;
    MMI_Modem_Send_Sms_Cnf_t     *    pSendSmsCnf;
    RIL_MSG_REQUEST_WRITE_SMS_TO_SIM * pWriteSmsReq;

    UINT16                           SmsPduLen;
    RIL_Errno                        RilResult;

    pSendSms  = (MMI_Modem_Send_Sms_Req_t *)Msg;
    SmsPduLen = strlen(pSendSms->pSmsPdu);

    if(MMI_MODEM_WRITE_TO_SIM == pSendSms->WriteToSimFlg) {
        g_ModemSmsMng.WriteToSim   = TRUE;
        g_ModemSmsMng.pSendSms_Pdu = Hal_Mem_Alloc(SmsPduLen + 1);
        memcpy(g_ModemSmsMng.pSendSms_Pdu, pSendSms->pSmsPdu, SmsPduLen);
        g_ModemSmsMng.pSendSms_Pdu[SmsPduLen] = 0;
    } else {
        g_ModemSmsMng.WriteToSim = FALSE;
    }

    pSendSmsReq = (RIL_MSG_REQUEST_SEND_SMS *)Hal_Mem_Alloc(sizeof(RIL_MSG_REQUEST_SEND_SMS));
    if(NULL != pSendSms->pSmsc) {
        pSendSmsReq->ucSmscAddrLen = strlen(pSendSms->pSmsc);
        pSendSmsReq->pcSmsc        = pSendSms->pSmsc; // send the pSmsPdu buffer to ril, do not free here!

        //     if(MMI_MODEM_WRITE_TO_SIM == pSendSms->WriteToSimFlg) {
        //     g_ModemSmsMng.pSendSms_Smsc = Hal_Mem_Alloc(pSendSmsReq->ucSmscAddrLen + 1);
        //     memcpy(g_ModemSmsMng.pSendSms_Smsc, pSendSms->pSmsc, pSendSmsReq->ucSmscAddrLen);
        //     g_ModemSmsMng.pSendSms_Smsc[pSendSmsReq->ucSmscAddrLen] = 0;
        // }
    } else {
        pSendSmsReq->ucSmscAddrLen = 0;
        pSendSmsReq->pcSmsc        = NULL;

        // g_ModemSmsMng.pSendSms_Smsc = NULL;
    }
    pSendSmsReq->ucSmsPduLen = SmsPduLen;
    pSendSmsReq->pSmsPdu     = pSendSms->pSmsPdu;   // send the pSmsPdu buffer to ril, do not free here!
    pSendSmsReq->eSimId      = MMI_ModemAdp_Get_Ril_SimId(pSendSms->SimId);
    RilResult                = Ril_MSG_Request_Send_Sms(pSendSmsReq);
    if (pSendSmsReq->pcSmsc) {
        Hal_Mem_Free(pSendSmsReq->pcSmsc);
    }
    if (pSendSmsReq->pSmsPdu) {
        Hal_Mem_Free(pSendSmsReq->pSmsPdu);
    }
    Hal_Mem_Free(pSendSmsReq);
    if(RIL_E_SUCCESS != RilResult) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "Ril request send sms failed: %d\n",
                   RilResult);

        if(TRUE == g_ModemSmsMng.WriteToSim) {
            pWriteSmsReq =
                (RIL_MSG_REQUEST_WRITE_SMS_TO_SIM *)Hal_Mem_Alloc(sizeof(
                            RIL_MSG_REQUEST_WRITE_SMS_TO_SIM));
            pWriteSmsReq->eSimId    = MMI_ModemAdp_Get_Ril_SimId(pSendSms->SimId);
            pWriteSmsReq->pSmsWrite =
                (RIL_SMS_WRITEARGS *)Hal_Mem_Alloc(sizeof(RIL_SMS_WRITEARGS));
            pWriteSmsReq->pSmsWrite->iStatus = 2;       // 2 = "STO UNSENT"
            pWriteSmsReq->pSmsWrite->pcPdu   = g_ModemSmsMng.pSendSms_Pdu;
            pWriteSmsReq->pSmsWrite->pcSmsc  = g_ModemSmsMng.pSendSms_Smsc[pSendSms->SimId];
            g_ModemSmsMng.pSendSms_Pdu       = NULL;
            // g_ModemSmsMng.pSendSms_Smsc      = NULL;

            RilResult = Ril_MSG_Request_Write_Sms_to_Sim(pWriteSmsReq);
            if(RIL_E_SUCCESS != RilResult) {
                UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                           "Ril request write sms to sim failed: %d\n", RilResult);
                pSendSmsCnf =
                    (MMI_Modem_Send_Sms_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Sms_Cnf_t));
                pSendSmsCnf->Result   = MMI_MODEM_SMS_FAIL;
                pSendSmsCnf->MsgIndex = MSG_INDEX_INVALID;
                pSendSmsCnf->SimId    = pSendSms->SimId;
                MMI_Modem_Send_Sms_Cnf(pSendSmsCnf);

                g_ModemSmsMng.SmsStatus[pSendSms->SimId] = MODEM_SMS_IDLE;

                // in case of memeory full
                if((RIL_E_NO_MEMORY == RilResult) || (RIL_E_SIM_FULL == RilResult)) {
                    // ril is expected to call "Response_Sms_Storage_Stauts" in this case, here do nothing
                }
            } else {
                g_ModemSmsMng.SendSms_Result             = MMI_MODEM_SMS_FAIL;
                g_ModemSmsMng.SmsStatus[pSendSms->SimId] = MODEM_SMS_WRITING;
            }
        } else {
            pSendSmsCnf =
                (MMI_Modem_Send_Sms_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Sms_Cnf_t));
            pSendSmsCnf->Result   = MMI_MODEM_SMS_FAIL;
            pSendSmsCnf->MsgIndex = MSG_INDEX_INVALID;
            pSendSmsCnf->SimId    = pSendSms->SimId;
            MMI_Modem_Send_Sms_Cnf(pSendSmsCnf);

            g_ModemSmsMng.SmsStatus[pSendSms->SimId] = MODEM_SMS_IDLE;
        }
    } else {
        g_ModemSmsMng.SmsStatus[pSendSms->SimId] = MODEM_SMS_SENDING;
    }
} /* MMI_ModemAdp_Sms_Send_Sms_Req_Handler */

/**
 * Handler of MMI_MODEMADP_DEL_SMS_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Sms_Delete_Sms_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modem_Delete_Sms_Req_t    *    pDeleteSms;
    RIL_MSG_REQUEST_DELETE_SMS_ON_SIM * pRilDeleteSms;
    RIL_Errno                         RilResult;
    UINT16                            i;

    MMI_MODEM_SMS_RESULT_TYPE         Result = MMI_MODEM_SMS_SUCCESS;

    pDeleteSms = (MMI_Modem_Delete_Sms_Req_t *)Msg;
    for(i = 0; i < pDeleteSms->DeleteMsgCnt; i++) {
        pRilDeleteSms =
            (RIL_MSG_REQUEST_DELETE_SMS_ON_SIM *)Hal_Mem_Alloc(sizeof(
                        RIL_MSG_REQUEST_DELETE_SMS_ON_SIM));
        pRilDeleteSms->ulDeleteIndex = pDeleteSms->pMsgIndex[i];
        pRilDeleteSms->eSimId        = MMI_ModemAdp_Get_Ril_SimId(pDeleteSms->SimId);
        RilResult                    = Ril_MSG_Request_Delete_Sms_On_Sim(pRilDeleteSms);
        if(RIL_E_SUCCESS != RilResult) {
            Result = MMI_MODEM_SMS_FAIL;
        }
    }
    MMI_Modem_Delete_Sms_Cnf(Result);

    // free the caller memory
    if(NULL != pDeleteSms->pMsgIndex) {
        Hal_Mem_Free(pDeleteSms->pMsgIndex);
    }
}

/**
 * Handler of MMI_MODEMADP_READ_SMS_INFO_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Sms_Read_Sms_Info_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modemadp_Read_Sms_Info_t * ReadSmsInfoReq;
    MMI_Modem_Read_Sms_Info_Cnf_t  * pReadSmsInfoCnf;

    RIL_Errno                       RilResult;

    ReadSmsInfoReq = (MMI_Modemadp_Read_Sms_Info_t *)Msg;
    if(MMI_MODEM_SMS_RECEIVED == ReadSmsInfoReq->SmsBox) {
        RilResult = Ril_MSG_Request_Read_Sms_Info_From_Sim(MSG_SMS_UNREAD);
        if(RIL_E_SUCCESS == RilResult) {
            gp_ModemSms_ReadSmsInfoCnf = NULL;
            g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_READING_MULTY_SMS_UNREAD;
            g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_READING_MULTY_SMS_UNREAD;
        } else {
            UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                       "Ril request read multiple sms failed(UNREAD): %d\n", RilResult);
            RilResult = Ril_MSG_Request_Read_Sms_Info_From_Sim(MSG_SMS_READ);
            if(RIL_E_SUCCESS == RilResult) {
                gp_ModemSms_ReadSmsInfoCnf = NULL;
                g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_READING_MULTY_SMS_READ;
                g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_READING_MULTY_SMS_READ;
            } else {
                UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                           "Ril request read multiple sms failed(READ): %d\n", RilResult);
                pReadSmsInfoCnf = (MMI_Modem_Read_Sms_Info_Cnf_t *)Hal_Mem_Alloc(
                                      sizeof(MMI_Modem_Read_Sms_Info_Cnf_t));
                pReadSmsInfoCnf->Result          = MMI_MODEM_SMS_FAIL;
                pReadSmsInfoCnf->SmsBox          = ReadSmsInfoReq->SmsBox;
                pReadSmsInfoCnf->ReadMsgCnt      = 0;
                pReadSmsInfoCnf->pMsgContentInfo = NULL;
                MMI_Modem_Read_Sms_Info_Cnf(pReadSmsInfoCnf);
            }
        }
    } else if(MMI_MODEM_SMS_SENT == ReadSmsInfoReq->SmsBox) {
        RilResult = Ril_MSG_Request_Read_Sms_Info_From_Sim(MSG_SMS_SENT);
        if(RIL_E_SUCCESS == RilResult) {
            g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_READING_MULTY_SMS_SENT;
            g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_READING_MULTY_SMS_SENT;
        } else {
            UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                       "Ril request read multiple sms failed(SENT): %d\n", RilResult);
            pReadSmsInfoCnf = (MMI_Modem_Read_Sms_Info_Cnf_t *)Hal_Mem_Alloc(
                                  sizeof(MMI_Modem_Read_Sms_Info_Cnf_t));
            pReadSmsInfoCnf->Result          = MMI_MODEM_SMS_FAIL;
            pReadSmsInfoCnf->SmsBox          = ReadSmsInfoReq->SmsBox;
            pReadSmsInfoCnf->ReadMsgCnt      = 0;
            pReadSmsInfoCnf->pMsgContentInfo = NULL;
            MMI_Modem_Read_Sms_Info_Cnf(pReadSmsInfoCnf);
        }
    } else if(MMI_MODEM_SMS_ALL == ReadSmsInfoReq->SmsBox) {
        RilResult = Ril_MSG_Request_Read_Sms_Info_From_Sim(MSG_SMS_ALL);
        if(RIL_E_SUCCESS == RilResult) {
            g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_READING_MULTY_SMS_ALL;
            g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_READING_MULTY_SMS_ALL;
        } else {
            UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                       "Ril request read multiple sms failed(ALL): %d\n", RilResult);
            pReadSmsInfoCnf = (MMI_Modem_Read_Sms_Info_Cnf_t *)Hal_Mem_Alloc(
                                  sizeof(MMI_Modem_Read_Sms_Info_Cnf_t));
            pReadSmsInfoCnf->Result          = MMI_MODEM_SMS_FAIL;
            pReadSmsInfoCnf->SmsBox          = ReadSmsInfoReq->SmsBox;
            pReadSmsInfoCnf->ReadMsgCnt      = 0;
            pReadSmsInfoCnf->pMsgContentInfo = NULL;
            MMI_Modem_Read_Sms_Info_Cnf(pReadSmsInfoCnf);
        }
    }
} /* MMI_ModemAdp_Sms_Read_Sms_Info_Req_Handler */

/**
 * Handler of MMI_MODEMADP_READ_SMS_DETAIL_ON_SIM_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Sms_Read_Sms_Detail_On_Sim_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modem_Read_Sms_Detail_On_Sim_Req_t  * pReadSmsReq;
    RIL_MSG_REQUEST_READ_SINGLE_SMS_FROM_SIM * pReadSingleSms;

    RIL_Errno                                RilResult;

    pReadSmsReq = (MMI_Modem_Read_Sms_Detail_On_Sim_Req_t *)Msg;

    pReadSingleSms =
        (RIL_MSG_REQUEST_READ_SINGLE_SMS_FROM_SIM *)Hal_Mem_Alloc(sizeof(
                    RIL_MSG_REQUEST_READ_SINGLE_SMS_FROM_SIM));
    pReadSingleSms->eSimId      = MMI_ModemAdp_Get_Ril_SimId(pReadSmsReq->SimId);
    pReadSingleSms->ulReadIndex = pReadSmsReq->MsgIndex;
    RilResult                   = Ril_MSG_Request_Read_Single_Sms_From_Sim(pReadSingleSms);
    if(RIL_E_SUCCESS == RilResult) {
        g_ModemSmsMng.SmsStatus[pReadSmsReq->SimId] = MODEM_SMS_READING_SINGLE_SMS;
    } else {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                   "Ril request read single sms failed on UI read command: %d\n", RilResult);
    }
}

/**
 * Handler of MMI_MODEMADP_GET_SMSC_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Sms_Get_Smsc_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modemadp_Sms_Get_Smsc_Req_t * GetSmscReq;
    MMI_Modem_Get_Smsc_Cnf_t      *     pGetSmscCnf;

    RIL_Errno                          RilResult;

    GetSmscReq = (MMI_Modemadp_Sms_Get_Smsc_Req_t *)Msg;
    RilResult  = Ril_MSG_Request_Get_Smsc_Addr(MMI_ModemAdp_Get_Ril_SimId(GetSmscReq->SimId));
    if(RIL_E_SUCCESS == RilResult) {
        // do nothing
    } else {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                   "Ril request get smsc addr failed: %d\n", RilResult);

        pGetSmscCnf =
            (MMI_Modem_Get_Smsc_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Get_Smsc_Cnf_t));
        pGetSmscCnf->Result = MMI_MODEM_SMS_FAIL;
        pGetSmscCnf->pSmsc  = NULL;
        pGetSmscCnf->SimId  = GetSmscReq->SimId;
        MMI_Modem_Get_Smsc_Cnf(pGetSmscCnf);
    }
}

/**
 * Handler of MMI_MODEMADP_SET_SMSC_REQ
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Sms_Set_Smsc_Req_Handler(UI_Inter_Msg_t * Msg)
{
    MMI_Modem_Set_Smsc_Req_t     *    pSetSmscReq;
    RIL_MSG_REQUEST_SET_SMSC_ADDRESS * pSetSmscAddr;

    RIL_Errno                        RilResult;

    pSetSmscReq = (MMI_Modem_Set_Smsc_Req_t *)Msg;

    pSetSmscAddr =
        (RIL_MSG_REQUEST_SET_SMSC_ADDRESS *)Hal_Mem_Alloc(sizeof(RIL_MSG_REQUEST_SET_SMSC_ADDRESS));
    pSetSmscAddr->eSimId = MMI_ModemAdp_Get_Ril_SimId(pSetSmscReq->SimId);
    if(NULL != pSetSmscReq->pSmsc) {
        pSetSmscAddr->ucSmscAddrLen = strlen(pSetSmscReq->pSmsc);
        pSetSmscAddr->pcSmsc        = Hal_Mem_Alloc(pSetSmscAddr->ucSmscAddrLen + 1);
        memset(pSetSmscAddr->pcSmsc, 0, pSetSmscAddr->ucSmscAddrLen + 1);
        memcpy(pSetSmscAddr->pcSmsc, pSetSmscReq->pSmsc, pSetSmscAddr->ucSmscAddrLen);
    } else {
        pSetSmscAddr->ucSmscAddrLen = 0;
        pSetSmscAddr->pcSmsc        = NULL;
    }

    RilResult = Ril_MSG_Request_Set_Smsc_Addr(pSetSmscAddr);
    if(RIL_E_SUCCESS == RilResult) {
        MMI_Modem_Set_Smsc_Cnf(MMI_MODEM_SMS_SUCCESS);
    } else {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                   "Ril request get smsc addr failed: %d\n", RilResult);
        MMI_Modem_Set_Smsc_Cnf(MMI_MODEM_SMS_FAIL);
    }

    // free the caller memory
    if(NULL != pSetSmscReq->pSmsc) {
        Hal_Mem_Free(pSetSmscReq->pSmsc);
    }
} /* MMI_ModemAdp_Sms_Set_Smsc_Req_Handler */

/******************************************************************************
 *
 *         Message Handler of RIL -> Modem Adaptor
 *
 *******************************************************************************/

/**
 * Handler of RIL_MODEMADP_MSG_RSP_SEND_SMS
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_Send_Sms_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_SEND_SMS    *    pSendSmsRes;
    app_adaptor_sms_send_result_ind   SmsSendResultIndFuncTemp = g_ModemSmsMng.SmsSendResultIndFunc;
#if 0
    MMI_Modem_Send_Sms_Cnf_t     *    pSendSmsCnf;
    RIL_MSG_REQUEST_WRITE_SMS_TO_SIM * pWriteSmsReq;

    RIL_Errno                        RilResult;
#endif

    pSendSmsRes = (RIL_MSG_RESPONSE_SEND_SMS *)Msg;

    if(0 == g_ModemSmsMng.MoSmsSegNum) {
        printf("%s: warning, wrong MoSmsSegNum\n", __FUNCTION__);
    } else {
        printf("%s: MoSmsSegNum %d, iErrorCode %d", __FUNCTION__, g_ModemSmsMng.MoSmsSegNum,
               pSendSmsRes->pSmsResponse->iErrorCode);
        g_ModemSmsMng.MoSmsSegNum--;

        if(0 != pSendSmsRes->pSmsResponse->iErrorCode) {
            if(SmsSendResultIndFuncTemp) {
                g_ModemSmsMng.SmsSendResultIndFunc = NULL;
                SmsSendResultIndFuncTemp(APP_SMS_SEND_FAIL);
            }
        } else if(0 == g_ModemSmsMng.MoSmsSegNum) {
            g_ModemSmsMng.SmsStatus[MMI_ModemAdp_Get_UI_SimId(pSendSmsRes->eSimId)] = MODEM_SMS_IDLE;
            if(SmsSendResultIndFuncTemp) {
                g_ModemSmsMng.SmsSendResultIndFunc = NULL;
                if(0 == pSendSmsRes->pSmsResponse->iErrorCode) {
                    SmsSendResultIndFuncTemp(APP_SMS_SEND_SUCCESS);
                } else {
                    SmsSendResultIndFuncTemp(APP_SMS_SEND_FAIL);
                }
            }
        }
    }

#if 0
    if(MODEM_SMS_SENDING == g_ModemSmsMng.SmsStatus[pSendSmsRes->eSimId]) {
        pSendSmsCnf = (MMI_Modem_Send_Sms_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Sms_Cnf_t));

        if(TRUE == g_ModemSmsMng.WriteToSim) {
            pWriteSmsReq =
                (RIL_MSG_REQUEST_WRITE_SMS_TO_SIM *)Hal_Mem_Alloc(sizeof(
                            RIL_MSG_REQUEST_WRITE_SMS_TO_SIM));
            pWriteSmsReq->eSimId    = pSendSmsRes->eSimId;
            pWriteSmsReq->pSmsWrite =
                (RIL_SMS_WRITEARGS *)Hal_Mem_Alloc(sizeof(RIL_SMS_WRITEARGS));
            pWriteSmsReq->pSmsWrite->iStatus = 3;       // 3 = "STO SENT"
            pWriteSmsReq->pSmsWrite->pcPdu   = g_ModemSmsMng.pSendSms_Pdu;
            pWriteSmsReq->pSmsWrite->pcSmsc = g_ModemSmsMng.pSendSms_Smsc[MMI_ModemAdp_Get_UI_SimId(pSendSmsRes->eSimId)];

            g_ModemSmsMng.pSendSms_Pdu       = NULL;
            // g_ModemSmsMng.pSendSms_Smsc      = NULL;

            RilResult = Ril_MSG_Request_Write_Sms_to_Sim(pWriteSmsReq);
            if(RIL_E_SUCCESS != RilResult) {
                UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                           "Ril request write sms to sim failed: %d\n", RilResult);
                pSendSmsCnf =
                    (MMI_Modem_Send_Sms_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Sms_Cnf_t));
                pSendSmsCnf->Result   = MMI_MODEM_SMS_SUCCESS;
                pSendSmsCnf->MsgIndex = MSG_INDEX_INVALID;
                pSendSmsCnf->SimId    = MMI_ModemAdp_Get_UI_SimId(pSendSmsRes->eSimId);
                MMI_Modem_Send_Sms_Cnf(pSendSmsCnf);

                g_ModemSmsMng.SmsStatus[pSendSmsRes->eSimId] = MODEM_SMS_IDLE;
            } else {
                g_ModemSmsMng.SendSms_Result                 = MMI_MODEM_SMS_SUCCESS;
                g_ModemSmsMng.SmsStatus[pSendSmsRes->eSimId] = MODEM_SMS_WRITING;
            }
        } else {
            pSendSmsCnf =
                (MMI_Modem_Send_Sms_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Sms_Cnf_t));
            pSendSmsCnf->Result   = MMI_MODEM_SMS_SUCCESS;
            pSendSmsCnf->MsgIndex = MSG_INDEX_INVALID;
            pSendSmsCnf->SimId    = MMI_ModemAdp_Get_UI_SimId(pSendSmsRes->eSimId);
            MMI_Modem_Send_Sms_Cnf(pSendSmsCnf);

            g_ModemSmsMng.SmsStatus[pSendSmsRes->eSimId] = MODEM_SMS_IDLE;
        }
    }
#endif

    // free the caller memory
    if(NULL != pSendSmsRes->pSmsResponse) {
        if(NULL != pSendSmsRes->pSmsResponse->pcAckPdu) {
            Hal_Mem_Free(pSendSmsRes->pSmsResponse->pcAckPdu);
        }
        Hal_Mem_Free(pSendSmsRes->pSmsResponse);
    }
} /* MMI_ModemAdp_Ril_Sms_Rsp_Send_Sms_Handler */

/**
 * Handler of RIL_MODEMADP_MSG_RSP_WRITE_SMS_TO_SIM
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_Write_Sms_To_Sim_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_WRITE_SMS_TO_SIM * pWriteSmsRes;
    MMI_Modem_Send_Sms_Cnf_t     *     pSendSmsCnf;

    pWriteSmsRes = (RIL_MSG_RESPONSE_WRITE_SMS_TO_SIM *)Msg;
    if(MODEM_SMS_WRITING == g_ModemSmsMng.SmsStatus[pWriteSmsRes->eSimId]) {
        pSendSmsCnf =
            (MMI_Modem_Send_Sms_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Send_Sms_Cnf_t));
        pSendSmsCnf->Result   = g_ModemSmsMng.SendSms_Result;
        pSendSmsCnf->MsgIndex = pWriteSmsRes->ulWriteIndex;
        pSendSmsCnf->SimId    = MMI_ModemAdp_Get_UI_SimId(pWriteSmsRes->eSimId);
        MMI_Modem_Send_Sms_Cnf(pSendSmsCnf);

        g_ModemSmsMng.SmsStatus[pWriteSmsRes->eSimId] = MODEM_SMS_IDLE;
    }
}

/**
 * Handler of RIL_MODEMADP_MSG_RSP_READ_SMS_INFO_FROM_SIM
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_Read_Sms_Info_From_Sim_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_READ_SMS_INFO_FROM_SIM * pReadSmsRes;
    MMI_Modem_Read_Sms_Info_Cnf_t      *     pReadSmsInfoCnf;
    MMI_Modem_Msg_Content_Info_t      *      pMsgContentInfo;

    RIL_Errno                               RilResult;
    UINT16                                  i;

    pReadSmsRes = (RIL_MSG_RESPONSE_READ_SMS_INFO_FROM_SIM *)Msg;
    if((MODEM_SMS_READING_MULTY_SMS_UNREAD == g_ModemSmsMng.SmsStatus[0])
            || (MODEM_SMS_READING_MULTY_SMS_UNREAD == g_ModemSmsMng.SmsStatus[1])) {
        pReadSmsInfoCnf =
            (MMI_Modem_Read_Sms_Info_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Read_Sms_Info_Cnf_t));
        pReadSmsInfoCnf->Result     = MMI_MODEM_SMS_SUCCESS;
        pReadSmsInfoCnf->SmsBox     = MMI_MODEM_SMS_RECEIVED;
        pReadSmsInfoCnf->ReadMsgCnt = pReadSmsRes->usSmsResCnt;
        if(0 != pReadSmsInfoCnf->ReadMsgCnt) {
            pReadSmsInfoCnf->pMsgContentInfo =
                (MMI_Modem_Msg_Content_Info_t *)Hal_Mem_Alloc(
                    sizeof(MMI_Modem_Msg_Content_Info_t) * pReadSmsInfoCnf->ReadMsgCnt);
            for(i = 0; i < pReadSmsInfoCnf->ReadMsgCnt; i++) {
                pReadSmsInfoCnf->pMsgContentInfo[i].MsgIndex =
                    pReadSmsRes->pSmsResponse[i].ulIndex;
                pReadSmsInfoCnf->pMsgContentInfo[i].ReadSmsType =
                    MMI_ModemAdp_Get_UI_Sms_Type(pReadSmsRes->pSmsResponse[i].eReadSmsType);
                pReadSmsInfoCnf->pMsgContentInfo[i].SimId =
                    MMI_ModemAdp_Get_UI_SimId(pReadSmsRes->pSmsResponse[i].eSimId);
            }
        } else {
            pReadSmsInfoCnf->pMsgContentInfo = NULL;
        }

        RilResult = Ril_MSG_Request_Read_Sms_Info_From_Sim(MSG_SMS_READ);
        if(RIL_E_SUCCESS == RilResult) {
            gp_ModemSms_ReadSmsInfoCnf = pReadSmsInfoCnf;
            g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_READING_MULTY_SMS_READ;
            g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_READING_MULTY_SMS_READ;
        } else {
            UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                       "Ril request read multiple sms failed(READ): %d\n", RilResult);
            MMI_Modem_Read_Sms_Info_Cnf(pReadSmsInfoCnf);
            g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_IDLE;
            g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_IDLE;
        }
    } else if((MODEM_SMS_READING_MULTY_SMS_READ == g_ModemSmsMng.SmsStatus[0])
              || (MODEM_SMS_READING_MULTY_SMS_READ == g_ModemSmsMng.SmsStatus[1])) {
        if(0 != pReadSmsRes->usSmsResCnt) {
            pMsgContentInfo =
                (MMI_Modem_Msg_Content_Info_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Msg_Content_Info_t) *
                        (pReadSmsRes->usSmsResCnt + gp_ModemSms_ReadSmsInfoCnf->ReadMsgCnt));
            // UNREAD is not empty
            if(0 != gp_ModemSms_ReadSmsInfoCnf->ReadMsgCnt) {
                // merge UNREAD into READ
                memcpy(pMsgContentInfo, gp_ModemSms_ReadSmsInfoCnf->pMsgContentInfo,
                       sizeof(MMI_Modem_Msg_Content_Info_t) * gp_ModemSms_ReadSmsInfoCnf->ReadMsgCnt);
                Hal_Mem_Free(gp_ModemSms_ReadSmsInfoCnf->pMsgContentInfo);
                gp_ModemSms_ReadSmsInfoCnf->pMsgContentInfo = pMsgContentInfo;
            }
            for(i = gp_ModemSms_ReadSmsInfoCnf->ReadMsgCnt;
                    i < (gp_ModemSms_ReadSmsInfoCnf->ReadMsgCnt + pReadSmsRes->usSmsResCnt); i++) {
                gp_ModemSms_ReadSmsInfoCnf->pMsgContentInfo[i].MsgIndex =
                    pReadSmsRes->pSmsResponse[i].ulIndex;
                gp_ModemSms_ReadSmsInfoCnf->pMsgContentInfo[i].ReadSmsType =
                    MMI_ModemAdp_Get_UI_Sms_Type(pReadSmsRes->pSmsResponse[i].eReadSmsType);
                gp_ModemSms_ReadSmsInfoCnf->pMsgContentInfo[i].SimId =
                    MMI_ModemAdp_Get_UI_SimId(pReadSmsRes->pSmsResponse[i].eSimId);
            }
            gp_ModemSms_ReadSmsInfoCnf->ReadMsgCnt += pReadSmsRes->usSmsResCnt;
            MMI_Modem_Read_Sms_Info_Cnf(gp_ModemSms_ReadSmsInfoCnf);
            g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_IDLE;
            g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_IDLE;
        }
    } else if((MODEM_SMS_READING_MULTY_SMS_SENT == g_ModemSmsMng.SmsStatus[0])
              ||
              (MODEM_SMS_READING_MULTY_SMS_SENT == g_ModemSmsMng.SmsStatus[1])) {
        pReadSmsInfoCnf =
            (MMI_Modem_Read_Sms_Info_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Read_Sms_Info_Cnf_t));
        pReadSmsInfoCnf->Result     = MMI_MODEM_SMS_SUCCESS;
        pReadSmsInfoCnf->SmsBox     = MMI_MODEM_SMS_SENT;
        pReadSmsInfoCnf->ReadMsgCnt = pReadSmsRes->usSmsResCnt;
        if(0 != pReadSmsInfoCnf->ReadMsgCnt) {
            pReadSmsInfoCnf->pMsgContentInfo =
                (MMI_Modem_Msg_Content_Info_t *)Hal_Mem_Alloc(
                    sizeof(MMI_Modem_Msg_Content_Info_t) * pReadSmsInfoCnf->ReadMsgCnt);
            for(i = 0; i < pReadSmsInfoCnf->ReadMsgCnt; i++) {
                pReadSmsInfoCnf->pMsgContentInfo[i].MsgIndex =
                    pReadSmsRes->pSmsResponse[i].ulIndex;
                pReadSmsInfoCnf->pMsgContentInfo[i].ReadSmsType =
                    MMI_ModemAdp_Get_UI_Sms_Type(pReadSmsRes->pSmsResponse[i].eReadSmsType);
                pReadSmsInfoCnf->pMsgContentInfo[i].SimId =
                    MMI_ModemAdp_Get_UI_SimId(pReadSmsRes->pSmsResponse[i].eSimId);
            }
        } else {
            pReadSmsInfoCnf->pMsgContentInfo = NULL;
        }

        MMI_Modem_Read_Sms_Info_Cnf(pReadSmsInfoCnf);
        g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_IDLE;
        g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_IDLE;
    } else if((MODEM_SMS_READING_MULTY_SMS_ALL == g_ModemSmsMng.SmsStatus[0])
              ||
              (MODEM_SMS_READING_MULTY_SMS_ALL == g_ModemSmsMng.SmsStatus[1])) {
        pReadSmsInfoCnf =
            (MMI_Modem_Read_Sms_Info_Cnf_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Read_Sms_Info_Cnf_t));
        pReadSmsInfoCnf->Result     = MMI_MODEM_SMS_SUCCESS;
        pReadSmsInfoCnf->SmsBox     = MMI_MODEM_SMS_SENT;
        pReadSmsInfoCnf->ReadMsgCnt = pReadSmsRes->usSmsResCnt;
        if(0 != pReadSmsInfoCnf->ReadMsgCnt) {
            pReadSmsInfoCnf->pMsgContentInfo =
                (MMI_Modem_Msg_Content_Info_t *)Hal_Mem_Alloc(
                    sizeof(MMI_Modem_Msg_Content_Info_t) * pReadSmsInfoCnf->ReadMsgCnt);
            for(i = 0; i < pReadSmsInfoCnf->ReadMsgCnt; i++) {
                pReadSmsInfoCnf->pMsgContentInfo[i].MsgIndex =
                    pReadSmsRes->pSmsResponse[i].ulIndex;
                pReadSmsInfoCnf->pMsgContentInfo[i].ReadSmsType =
                    MMI_ModemAdp_Get_UI_Sms_Type(pReadSmsRes->pSmsResponse[i].eReadSmsType);
                pReadSmsInfoCnf->pMsgContentInfo[i].SimId =
                    MMI_ModemAdp_Get_UI_SimId(pReadSmsRes->pSmsResponse[i].eSimId);
            }
        } else {
            pReadSmsInfoCnf->pMsgContentInfo = NULL;
        }

        MMI_Modem_Read_Sms_Info_Cnf(pReadSmsInfoCnf);
        g_ModemSmsMng.SmsStatus[0] = MODEM_SMS_IDLE;
        g_ModemSmsMng.SmsStatus[1] = MODEM_SMS_IDLE;
    }

    // free the caller memory
    if(0 != pReadSmsRes->usSmsResCnt) {
        Hal_Mem_Free(pReadSmsRes->pSmsResponse);
    }
} /* MMI_ModemAdp_Ril_Sms_Rsp_Read_Sms_Info_From_Sim_Handler */

/**
 * Handler of RIL_MODEMADP_MSG_RSP_READ_SINGLE_SMS_FROM_SIM
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_Read_Single_Sms_From_Sim_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_READ_SMS_FROM_SIM   *  pReadSingleSmsRes;
    MMI_Modem_Report_New_Sms_Ind_t     *    pRepNewSms;
    MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t * pReadSmsCnf;

    pReadSingleSmsRes = (RIL_MSG_RESPONSE_READ_SMS_FROM_SIM *)Msg;
    if(NULL != pReadSingleSmsRes->pcPdu) {
        if(MODEM_SMS_NEW_SMS_READING_SINGLE_SMS ==
                g_ModemSmsMng.SmsStatus[pReadSingleSmsRes->eSimId]) {
            pRepNewSms =
                (MMI_Modem_Report_New_Sms_Ind_t *)Hal_Mem_Alloc(sizeof(
                            MMI_Modem_Report_New_Sms_Ind_t));
            pRepNewSms->MsgContentInfo.MsgIndex = pReadSingleSmsRes->ulIndex;
            pRepNewSms->MsgContentInfo.SimId    = MMI_ModemAdp_Get_UI_SimId(
                    pReadSingleSmsRes->eSimId);
            pRepNewSms->MsgContentInfo.ReadSmsType =
                MMI_ModemAdp_Get_UI_Sms_Type(pReadSingleSmsRes->eReadSmsType);
            MMI_Modem_Rep_New_Sms_Ind(pRepNewSms);
        } else if(MODEM_SMS_READING_SINGLE_SMS == g_ModemSmsMng.SmsStatus[pReadSingleSmsRes->eSimId]) {
            pReadSmsCnf =
                (MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t *)Hal_Mem_Alloc(sizeof(
                            MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t));
            pReadSmsCnf->Result  = MMI_MODEM_SMS_SUCCESS;
            pReadSmsCnf->pSmsPdu = Hal_Mem_Alloc(pReadSingleSmsRes->usSmsPduLen + 1);
            memset(pReadSmsCnf->pSmsPdu, 0, pReadSingleSmsRes->usSmsPduLen + 1);
            memcpy(pReadSmsCnf->pSmsPdu, pReadSingleSmsRes->pcPdu, pReadSingleSmsRes->usSmsPduLen);
            pReadSmsCnf->MsgIndex = pReadSingleSmsRes->ulIndex;
            pReadSmsCnf->SimId    = MMI_ModemAdp_Get_UI_SimId(pReadSingleSmsRes->eSimId);
            MMI_Modem_Read_Sms_Detail_On_Sim_Cnf(pReadSmsCnf);
        }
    } else {
        if(MODEM_SMS_NEW_SMS_READING_SINGLE_SMS ==
                g_ModemSmsMng.SmsStatus[pReadSingleSmsRes->eSimId]) {
            UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                       "Ril response read single sms failed on receiving new sms: PDU is NULL!\n");
        } else if(MODEM_SMS_READING_SINGLE_SMS == g_ModemSmsMng.SmsStatus[pReadSingleSmsRes->eSimId]) {
            pReadSmsCnf =
                (MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t *)Hal_Mem_Alloc(sizeof(
                            MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t));
            pReadSmsCnf->Result   = MMI_MODEM_SMS_FAIL;
            pReadSmsCnf->pSmsPdu  = NULL;
            pReadSmsCnf->MsgIndex = pReadSingleSmsRes->ulIndex;
            pReadSmsCnf->SimId    = MMI_ModemAdp_Get_UI_SimId(pReadSingleSmsRes->eSimId);
            MMI_Modem_Read_Sms_Detail_On_Sim_Cnf(pReadSmsCnf);
        }
    }
    g_ModemSmsMng.SmsStatus[pReadSingleSmsRes->eSimId] = MODEM_SMS_IDLE;

    // free the caller memory
    if(NULL != pReadSingleSmsRes->pcPdu) {
        Hal_Mem_Free(pReadSingleSmsRes->pcPdu);
    }
} /* MMI_ModemAdp_Ril_Sms_Rsp_Read_Single_Sms_From_Sim_Handler */

static uint32_t ctoi(char *s)
{
    uint32_t i, m, temp = 0, n;

    m = strlen(s);

    for(i = 0; i < m; i++) {
        if(s[i] >= 'A' && s[i] <= 'F') n = s[i] - 'A' + 10;
        else if(s[i] >= 'a' && s[i] <= 'f') n = s[i] - 'a' + 10;
        else n = s[i] - '0';
        temp = temp * 16 + n;
    }

    return temp;
}

/**
 * Handler of RIL_MODEMADP_MSG_RSP_GET_SMSC_ADDR
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_Get_Smsc_Addr_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_GET_SMSC_ADDRESS * pGetSmscAddr;
    char  *  SmscStart = NULL;
    char     SmscLen[3] = {0};
    uint16_t  SmscPduLen = 0;
    INT8   *  pSmscPdu = NULL;

    pGetSmscAddr = (RIL_MSG_RESPONSE_GET_SMSC_ADDRESS *)Msg;
    if(0 == pGetSmscAddr->ucSmscAddrLen) {
        return;
    }

    SmscStart = &pGetSmscAddr->pcSmsc[pGetSmscAddr->ucSmscAddrLen - 14 * 2];
    strncpy(SmscLen, SmscStart, 2);
    SmscPduLen = ctoi(SmscLen) * 2 + 2;
    printf("smsc_len is %d\n", SmscPduLen);

    if(SmscPduLen > 20) {
        SmscStart = &pGetSmscAddr->pcSmsc[pGetSmscAddr->ucSmscAddrLen - 15 * 2];
        strncpy(SmscLen, SmscStart, 2);
        SmscPduLen = ctoi(SmscLen) * 2 + 2;
        printf("smsc_len is %d\n", SmscPduLen);
    }

    pSmscPdu = (char *)lv_mem_alloc(SmscPduLen + 1);
    memset(pSmscPdu, 0, SmscPduLen + 1);
    strncpy(pSmscPdu, SmscStart, SmscPduLen);

    printf("pSmscPdu is %s\n", pSmscPdu);
    g_ModemSmsMng.pSendSms_Smsc[MMI_ModemAdp_Get_UI_SimId(pGetSmscAddr->eSimId)] = pSmscPdu;

    // free the ril buffer
    if(NULL != pGetSmscAddr->pcSmsc) {
        Hal_Mem_Free(pGetSmscAddr->pcSmsc);
    }
}

/**
 * Handler of RIL_MODEMADP_MSG_RSP_NEW_SMS_ON_SIM
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_New_Sms_On_Sim_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_NEW_SMS_ON_SIM     *     pNewSmsOnSim;
    RIL_MSG_REQUEST_READ_SINGLE_SMS_FROM_SIM * pReadSingleSms;

    RIL_Errno                                RilResult;

    pNewSmsOnSim = (RIL_MSG_RESPONSE_NEW_SMS_ON_SIM *)Msg;

    pReadSingleSms =
        (RIL_MSG_REQUEST_READ_SINGLE_SMS_FROM_SIM *)Hal_Mem_Alloc(sizeof(
                    RIL_MSG_REQUEST_READ_SINGLE_SMS_FROM_SIM));
    pReadSingleSms->eSimId      = pNewSmsOnSim->eSimId;
    pReadSingleSms->ulReadIndex = pNewSmsOnSim->iIndex;
    RilResult                   = Ril_MSG_Request_Read_Single_Sms_From_Sim(pReadSingleSms);
    if(RIL_E_SUCCESS == RilResult) {
        g_ModemSmsMng.SmsStatus[pNewSmsOnSim->eSimId] = MODEM_SMS_NEW_SMS_READING_SINGLE_SMS;
    } else {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR,
                   "Ril request read single sms failed on receiving new sms: %d\n", RilResult);
    }
}

/**
 * Handler of RIL_MODEMADP_MSG_RSP_SMS_STATUS_REP
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_Sms_Status_Report_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_SMS_STATUS_REP     *    pSmsStsRep;
    MMI_Modem_Response_Sms_Status_Rep_Ind_t * pMmiSmsStsRep;

    pSmsStsRep = (RIL_MSG_RESPONSE_SMS_STATUS_REP *)Msg;
    if(TRUE == g_ModemSmsMng.DeliverStatusReport[pSmsStsRep->eSimId]) {
        pMmiSmsStsRep = (MMI_Modem_Response_Sms_Status_Rep_Ind_t *)Hal_Mem_Alloc(
                            sizeof(MMI_Modem_Response_Sms_Status_Rep_Ind_t));
        pMmiSmsStsRep->SimId         = MMI_ModemAdp_Get_UI_SimId(pSmsStsRep->eSimId);
        pMmiSmsStsRep->pSmsStatusRep = pSmsStsRep->pSmsStatusRep;  // continue used by MMI, do not free here!
        MMI_Modem_Sms_Status_Rep_Ind(pMmiSmsStsRep);
    } else {
        // if no need to send status report, free the ril memory
        if(NULL != pSmsStsRep->pSmsStatusRep) {
            Hal_Mem_Free(pSmsStsRep->pSmsStatusRep);
        }
    }
}

/**
 * Handler of RIL_MODEMADP_MSG_RSP_SMS_STORAGE_STATUS
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_Sms_Storage_Status_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_SMS_STORAGE_STATUS  *  pSmsStorageSts;
    MMI_Modem_SIM_SMS_Storage_Status_Ind_t * pRepSimSmsStaInd;

    pSmsStorageSts = (RIL_MSG_RESPONSE_SMS_STORAGE_STATUS *)Msg;

    pRepSimSmsStaInd =
        (MMI_Modem_SIM_SMS_Storage_Status_Ind_t *)Hal_Mem_Alloc(sizeof(
                    MMI_Modem_SIM_SMS_Storage_Status_Ind_t));
    pRepSimSmsStaInd->SimId = MMI_ModemAdp_Get_UI_SimId(pSmsStorageSts->eSimId);
    if(RIL_SIM_READY_FOR_SMS == pSmsStorageSts->ucSimReady) {
        pRepSimSmsStaInd->SimReady = TRUE;
    } else {
        pRepSimSmsStaInd->SimReady = FALSE;
    }

    if(RIL_SIM_FULL_FOR_SMS == pSmsStorageSts->ucSimFull) {
        pRepSimSmsStaInd->SimFull = TRUE;
    } else {
        pRepSimSmsStaInd->SimFull = FALSE;
    }
    MMI_Modem_SIM_SMS_Storage_Status_Ind(pRepSimSmsStaInd);
}

/**
 * Handler of RIL_MODEMADP_MSG_RSP_NEW_SMS
 * param (in) Msg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Ril_Sms_Rsp_New_Sms_Handler(UI_Inter_Msg_t * Msg)
{
    RIL_MSG_RESPONSE_NEW_SMS * pNewSms;
    INT8 number[40] = {};
    INT8 time[20] = {};
    INT8 data[160 * 2] = {};
    app_adp_new_sms_info_ind_t * pSmsInfo;
    uint16_t data_len = 0;
    uint8_t udhi = 0;
    uint8_t dcs = 0;

    pNewSms = (RIL_MSG_RESPONSE_NEW_SMS *)Msg;

    if(0 == pNewSms->usSmsLen) {
        UI_Log_Out(UI_SUB_MODULE_MODEM_ADP, UI_LOG_LEVEL_ERROR, "New Sms from Ril is empty!\n");
        return;
    }

    data_len = DecodeSmsPdu(pNewSms->pNewSms, number, time, data, g_ModemSmsMng.decode_type, &udhi, &dcs);

    if(0 == udhi) {
        pSmsInfo = (app_adp_new_sms_info_ind_t *)Hal_Mem_Alloc(sizeof(app_adp_new_sms_info_ind_t));
        Hal_Mem_Set(pSmsInfo, 0, sizeof(app_adp_new_sms_info_ind_t));

        pSmsInfo->number_len = strlen(number);
        pSmsInfo->number = (INT8 *)Hal_Mem_Alloc(pSmsInfo->number_len + 1);
        Hal_Mem_Set(pSmsInfo->number, 0, pSmsInfo->number_len + 1);
        Hal_Mem_Copy(pSmsInfo->number, number, pSmsInfo->number_len);

        pSmsInfo->time_len = strlen(time);
        pSmsInfo->time = (INT8 *)Hal_Mem_Alloc(pSmsInfo->time_len + 1);
        Hal_Mem_Set(pSmsInfo->time, 0, pSmsInfo->time_len + 1);
        Hal_Mem_Copy(pSmsInfo->time, time, pSmsInfo->time_len);

        pSmsInfo->data_len = data_len;
        pSmsInfo->data = (INT8 *)Hal_Mem_Alloc(pSmsInfo->data_len + 1);
        Hal_Mem_Set(pSmsInfo->data, 0, pSmsInfo->data_len + 1);
        Hal_Mem_Copy(pSmsInfo->data, data, pSmsInfo->data_len);

        if(4 == dcs) {
            if(g_ModemSmsMng.New8bitSmsInfoIndFunc != NULL) {
                g_ModemSmsMng.New8bitSmsInfoIndFunc(pSmsInfo);
            } else {
                Hal_Mem_Free(pSmsInfo->number);
                Hal_Mem_Free(pSmsInfo->time);
                Hal_Mem_Free(pSmsInfo->data);
                Hal_Mem_Free(pSmsInfo);
            }
        } else {
            if(g_ModemSmsMng.NewSmsInfoIndFunc != NULL) {
                g_ModemSmsMng.NewSmsInfoIndFunc(pSmsInfo);
            } else {
                Hal_Mem_Free(pSmsInfo->number);
                Hal_Mem_Free(pSmsInfo->time);
                Hal_Mem_Free(pSmsInfo->data);
                Hal_Mem_Free(pSmsInfo);
            }
        }
    } else {
        if((0 < data_len) && (4 != dcs)) {
            pSmsInfo = (app_adp_new_sms_info_ind_t *)Hal_Mem_Alloc(sizeof(app_adp_new_sms_info_ind_t));
            Hal_Mem_Set(pSmsInfo, 0, sizeof(app_adp_new_sms_info_ind_t));

            pSmsInfo->number_len = strlen(number);
            pSmsInfo->number = (INT8 *)Hal_Mem_Alloc(pSmsInfo->number_len + 1);
            Hal_Mem_Set(pSmsInfo->number, 0, pSmsInfo->number_len + 1);
            Hal_Mem_Copy(pSmsInfo->number, number, pSmsInfo->number_len);

            pSmsInfo->time_len = strlen(time);
            pSmsInfo->time = (INT8 *)Hal_Mem_Alloc(pSmsInfo->time_len + 1);
            Hal_Mem_Set(pSmsInfo->time, 0, pSmsInfo->time_len + 1);
            Hal_Mem_Copy(pSmsInfo->time, time, pSmsInfo->time_len);

            pSmsInfo->data = DecodeSegPdu(&pSmsInfo->data_len, dcs, g_ModemSmsMng.decode_type);

            if(g_ModemSmsMng.NewSmsInfoIndFunc != NULL) {
                g_ModemSmsMng.NewSmsInfoIndFunc(pSmsInfo);
            } else {
                Hal_Mem_Free(pSmsInfo->number);
                Hal_Mem_Free(pSmsInfo->time);
                if(NULL != pSmsInfo->data) {
                    Hal_Mem_Free(pSmsInfo->data);
                    pSmsInfo->data = NULL;
                }
                Hal_Mem_Free(pSmsInfo);
            }
        }
    }

    // free the ril buffer
    if(NULL != pNewSms->pNewSms) {
        Hal_Mem_Free(pNewSms->pNewSms);
    }
}

/**
 * module event handler
 * param (in) MsgId: UI_INTER_MSG_ID
 *       (in) pMsg: UI_Inter_Msg_t*
 * return  void
 */
VOID MMI_ModemAdp_Sms_Msg_handle(UI_INTER_MSG_ID MsgId, UI_Inter_Msg_t * pMsg)
{
    switch(MsgId) {
        case MMI_MODEMADP_SEND_SMS_REQ:
            MMI_ModemAdp_Sms_Send_Sms_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_DEL_SMS_REQ:
            MMI_ModemAdp_Sms_Delete_Sms_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_READ_SMS_INFO_REQ:
            MMI_ModemAdp_Sms_Read_Sms_Info_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_READ_SMS_DETAIL_ON_SIM_REQ:
            MMI_ModemAdp_Sms_Read_Sms_Detail_On_Sim_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_GET_SMSC_REQ:
            MMI_ModemAdp_Sms_Get_Smsc_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_SET_SMSC_REQ:
            MMI_ModemAdp_Sms_Set_Smsc_Req_Handler(pMsg);
            break;

        case MMI_MODEMADP_OPEN_VOLTE_REQ:
            MMI_ModemAdp_Open_Volte_Req_Handler(pMsg);
            break;
        // case MMI_MODEMADP_SET_DELIVERY_REP_REQ:

        case RIL_MODEMADP_MSG_RSP_SEND_SMS:
            MMI_ModemAdp_Ril_Sms_Rsp_Send_Sms_Handler(pMsg);
            break;

        case RIL_MODEMADP_MSG_RSP_WRITE_SMS_TO_SIM:
            MMI_ModemAdp_Ril_Sms_Rsp_Write_Sms_To_Sim_Handler(pMsg);
            break;

        case RIL_MODEMADP_MSG_RSP_READ_SMS_INFO_FROM_SIM:
            MMI_ModemAdp_Ril_Sms_Rsp_Read_Sms_Info_From_Sim_Handler(pMsg);
            break;

        case RIL_MODEMADP_MSG_RSP_READ_SINGLE_SMS_FROM_SIM:
            MMI_ModemAdp_Ril_Sms_Rsp_Read_Single_Sms_From_Sim_Handler(pMsg);
            break;

        case RIL_MODEMADP_MSG_RSP_GET_SMSC_ADDR:
            MMI_ModemAdp_Ril_Sms_Rsp_Get_Smsc_Addr_Handler(pMsg);
            break;

        case RIL_MODEMADP_MSG_RSP_NEW_SMS_ON_SIM:
            MMI_ModemAdp_Ril_Sms_Rsp_New_Sms_On_Sim_Handler(pMsg);
            break;

        case RIL_MODEMADP_MSG_RSP_SMS_STATUS_REP:
            MMI_ModemAdp_Ril_Sms_Rsp_Sms_Status_Report_Handler(pMsg);
            break;

        case RIL_MODEMADP_MSG_RSP_SMS_STORAGE_STATUS:
            MMI_ModemAdp_Ril_Sms_Rsp_Sms_Storage_Status_Handler(pMsg);
            break;
        // case RIL_MODEMADP_MSG_RSP_GET_BROADCAST_SMS_CFG:

        case RIL_MODEMADP_MSG_RSP_NEW_SMS:
            MMI_ModemAdp_Ril_Sms_Rsp_New_Sms_Handler(pMsg);
            break;

        // case RIL_MODEMADP_MSG_RSP_NEW_BROADCAST_SMS:

        default:
            break;
    } /* switch */
}     /* MMI_ModemAdp_Sms_Event_handle */

/**
 * Get UI Sms Type
 * param (in) RilSmsType:  RIL_MSG_READ_SMS_TYPE
 * return  MMI_MODEM_READ_SMS_TYPE
 */
MMI_MODEM_READ_SMS_TYPE MMI_ModemAdp_Get_UI_Sms_Type(RIL_MSG_READ_SMS_TYPE RilSmsType)
{
    switch(RilSmsType) {
        case MSG_SMS_UNREAD:
            return(MMI_MODEM_UNREAD);

        case MSG_SMS_READ:
            return(MMI_MODEM_READ);

        case MSG_SMS_UNSENT:
            return(MMI_MODEM_UNSENT);

        case MSG_SMS_SENT:
            return(MMI_MODEM_SENT);

        default:
            return(MMI_MODEM_UNSENT);
    }
}

void Ril_MSG_Response_New_Sms(RIL_MSG_RESPONSE_NEW_SMS * pNewSms)
{
    if(gcf_test) {
        Hal_Mem_Free(pNewSms->pNewSms);
        Hal_Mem_Free(pNewSms);
        return;
    }

    printf("##interface## %s\n", __FUNCTION__);
    UI_Send_Inter_Msg(UI_SUB_MODULE_MODEM_ADP, RIL_MODEMADP_MSG_RSP_NEW_SMS,
                      (UI_Inter_Msg_t *)pNewSms);
}

VOID Ril_EEM_Response_MMSG_IND(RIL_SIM_ID sid, unsigned char smsReady)
{
    printf("##interface## %s\n", __FUNCTION__);
    if(1 == smsReady) {
        if(NULL == g_ModemSmsMng.pSendSms_Smsc[MMI_ModemAdp_Get_UI_SimId(sid)]) {
            Ril_MSG_Request_Get_Smsc_Addr(sid);
        }
    }
}

static uint8_t SevenBitEncodeAlphabetExchange(uint8_t Data)
{
    uint8_t tmpData = Data;

    switch(tmpData) {
        case 0x40:// '@'
            tmpData = 0x00;
            break;
        case 0x24:// '$'
            tmpData = 0x02;
            break;
        case 0x5F:// '_'
            tmpData = 0x11;
            break;
        case 0x5B:// '['
        case 0x5C:// '\'
        case 0x5D:// ']'
        case 0x5E:// '^'
        case 0x60:// '`'
        case 0x7B:// '{'
        case 0x7C:// '|'
        case 0x7D:// '}'
        case 0x7E:// '~'
        case 0x7F:// DEL
            tmpData = 0x20;
            break;
        default:
            break;
    }

    return tmpData;
}

static uint32_t EightBitStrToSevenBitData(char * p8BitStr, uint8_t * p7BitData, uint32_t EightBitStrlen)
{
    uint32_t i = 0;
    uint32_t j = 0;
    uint32_t k = 0;
    uint32_t count = 0;
    uint8_t tmp8BitData = 0;

    while(j < EightBitStrlen) {
        // p7BitData[k] = (uint8_t)(p8BitStr[j++] & 0x7F);
        tmp8BitData = SevenBitEncodeAlphabetExchange((uint8_t)(p8BitStr[j++]));
        p7BitData[k] = (tmp8BitData & 0x7F);

        i = 0;

        while(i < 7 && j < EightBitStrlen) {
            // p7BitData[k++] |= (uint8_t)(p8BitStr[j] << (7 - i));
            // p7BitData[k] = (uint8_t)(p8BitStr[j] >> (i + 1));
            tmp8BitData = SevenBitEncodeAlphabetExchange((uint8_t)(p8BitStr[j]));
            p7BitData[k++] |= (tmp8BitData << (7 - i));
            p7BitData[k] = (tmp8BitData >> (i + 1));
            i++;
            j++;
        }
    }

    if(EightBitStrlen%8)
    {
        count = k + 1;
    }
    else
    {
        count = k;
    }

    return count;
}

static bool AsciiToGSMBCD(char * pNumber, uint8_t * pBCD)
{
    char cINT8;
    uint32_t i;
    uint32_t len;
    uint8_t * pTmp;

    if((NULL == pNumber) || (NULL == pBCD))
        return false;

    pTmp = pBCD;
    len = strlen(pNumber);

    memset(pBCD, 0, strlen((char *)pBCD));

    for(i = 0; i < len; i++) {
        switch(*pNumber) {
            case '*':
                cINT8 = (char)0x0A;
                break;
            case '#':
                cINT8 = (char)0x0B;
                break;
            default:
                cINT8 = (char)(*pNumber - '0');
                break;
        }

        if(i % 2) {
            *pTmp++ |= ((cINT8 << 4) & 0xF0);
        } else {
            *pTmp = (char)(cINT8 & 0x0F);
        }

        pNumber++;
    }

    if(i % 2) {
        *pTmp |= 0xF0;
    }

    return true;
}

static void ConvertPduToHex(uint8_t * pPDU, uint8_t * pHight, uint8_t * pLow)
{
    char cTmp;

    if(pPDU == NULL || pHight == NULL || pLow == NULL)
        return;

    cTmp = (char)((*pPDU) >> 4);

    if(cTmp < 10)
        *pHight = (uint8_t)('0' + cTmp);
    else
        *pHight = (uint8_t)('A' + cTmp - 10);

    cTmp = (char)((*pPDU) & 0x0F);

    if(cTmp < 10)
        *pLow = (uint8_t)('0' + cTmp);
    else
        *pLow = (uint8_t)('A' + cTmp - 10);
}

uint32_t EncodeSmsc(char * smscNum, uint32_t smscNumLen, uint8_t * pSmscPdu)
{
    uint32_t uPos = 0;
    uint32_t i = 0;
    uint8_t BCDSmscNum[25] = {0};
    uint8_t PDU[140 + 40];
    uint8_t * pPDUData = PDU;
    uint32_t BCDSmscCnt = 0;
    char * tmpNum = smscNum;
    uint32_t tmpLen = smscNumLen;

    memset(PDU, 0, 140 + 40);
    if(strstr(smscNum, (char *)"+")) {
        tmpNum = smscNum + 1;
        tmpLen = smscNumLen - 1;
    }

    if(false == AsciiToGSMBCD(tmpNum, BCDSmscNum)) {
        return uPos;
    }

    if(0 == (tmpLen % 2)) {
        BCDSmscCnt = tmpLen / 2;
    } else {
        BCDSmscCnt = tmpLen / 2 + 1;
    }

    pPDUData[uPos++] = BCDSmscCnt + 1;
    pPDUData[uPos++] = 0x91;
    // pPDUData[uPos++] = 0x68;
    memcpy((pPDUData + uPos), BCDSmscNum, BCDSmscCnt);
    uPos += BCDSmscCnt;

    for(i = 0; i < uPos; i++) {
        ConvertPduToHex(&PDU[i], pSmscPdu, pSmscPdu + 1);
        pSmscPdu += 2;
    }

    return uPos;
}

void EncodeSmsPdu(char * data, char * phoneNumIn, Modem_SMS_Encode_Pdu_t * pSmsPdu, uint8_t encode_type, uint32_t datalen)
{
    uint32_t uPos = 0;
    int32_t i = 0;
    uint32_t BCDlen = 0;
    uint8_t BCDnum[40] = {};
    char    phoneNum[40] = {};
    uint8_t * pPDUData = pSmsPdu->Data;
    uint8_t dcs = 0x00;
    uint32_t sevenbit_len = 0;
    uint8_t udhi = 0;
    uint8_t headerlen = 0;
    uint8_t charsnum = 0;
    uint32_t seglen = 0;
    uint8_t segnum = 0;
    uint16_t c_uni;
    Modem_SMS_Encode_Pdu_t * Pdu = pSmsPdu;
    bool international_number = false;

    if((0x2B == phoneNumIn[0])
            && (0x38 == phoneNumIn[1])
            && (0x36 == phoneNumIn[2])) { // delete +86
        memcpy(phoneNum, &phoneNumIn[3], strlen(phoneNumIn) - 3);
    } else if((0x38 == phoneNumIn[0])
              && (0x36 == phoneNumIn[1])) { // delete 86
        memcpy(phoneNum, &phoneNumIn[2], strlen(phoneNumIn) - 2);
    } else if(0x2B == phoneNumIn[0]) { // delete +
        memcpy(phoneNum, &phoneNumIn[1], strlen(phoneNumIn) - 1);
        international_number = true;
    } else {
        memcpy(phoneNum, phoneNumIn, strlen(phoneNumIn));
    }

    if(false == AsciiToGSMBCD(phoneNum, BCDnum)) {
        return;
    }

    if(APP_SMS_CODE_TYPE_UTF_8 == encode_type) { //utf-8
        // check 7-bit encode or unicode encode
        for(i = 0; i < strlen(data); i++) {
            if(0 != (0x80 & data[i])) {
                dcs = 0x08;
                break;
            }
        }
        if(0x00 == dcs) {
            if(160 < datalen) {
                udhi = 1;
            }
        } else {
            while(datalen > seglen) {
                _lv_txt_encoded_next(data, &seglen);
                charsnum++;
                if(70 < charsnum) {
                    udhi = 1;
                    break;
                }
            }
        }
    } else if(APP_SMS_CODE_TYPE_UTF_16 == encode_type) { //utf-16
        dcs = 0x08;
        if(140 < datalen) {
            udhi = 1;
        }
    } else { //8-bit
        dcs = 0x04;
        if(140 < datalen) {
            udhi = 1;
        }
    }

    // TP-MTI,TP-RD,TP-VPF,TP-UDHI,TP-RP
    if(0 == udhi) {
        pPDUData[uPos++] = 0x11;
    } else {
        pPDUData[uPos++] = 0x51;
    }
    // TP-MR
    pPDUData[uPos++] = 0x00;
    // TP-DA
    pPDUData[uPos++] = strlen(phoneNum);
    if(international_number) {
        pPDUData[uPos++] = 0x91;
    } else {
        pPDUData[uPos++] = 0x81;
    }

    if(strlen(phoneNum) % 2) {
        BCDlen = strlen(phoneNum) / 2 + 1;
    } else {
        BCDlen = strlen(phoneNum) / 2;
    }

    memcpy((pPDUData + uPos), BCDnum, BCDlen);
    uPos += BCDlen;

    // TP-PID
    pPDUData[uPos++] = 0x00;
    // TP-DCS
    pPDUData[uPos++] = dcs;
    // TP-VP
    pPDUData[uPos++] = 0x00;

    headerlen = uPos;

    printf("%s: headerlen %d, datalen %d, BCDlen %d, phoneNum %s\n",
           __FUNCTION__, headerlen, datalen, BCDlen, phoneNum);

    while(0 < datalen) {
        // TP-UDL;
        uPos++;

        //TP-UD
        if(1 == udhi) {
            // TP-UDH
            pPDUData[uPos++] = 0x05;
            pPDUData[uPos++] = 0x00;
            pPDUData[uPos++] = 0x03;
            pPDUData[uPos++] = g_ModemSmsMng.RefNum;
            uPos++; // the number of segment
            pPDUData[uPos++] = ++segnum;
        }

        seglen = datalen;
        if(0x00 == dcs) {
            if(1 == udhi) {
                pPDUData[uPos++] = (*data) << 1; // set the filling bits to 0
                data++;
                datalen--;
                if(152 < datalen) {
                    seglen = 152;
                } else {
                    seglen = datalen;
                }
                pPDUData[headerlen] = 8 + seglen;
            } else {
                pPDUData[headerlen] = seglen;
            }
            sevenbit_len = EightBitStrToSevenBitData(data, &pPDUData[uPos], seglen);
            uPos += sevenbit_len;
        } else if(APP_SMS_CODE_TYPE_UTF_8 == encode_type) {
            charsnum = 0;
            seglen = 0;
            while(datalen > seglen) {
                c_uni = _lv_txt_encoded_next(data, &seglen);
                pPDUData[uPos++] = (uint8_t)(c_uni >> 8);
                pPDUData[uPos++] = (uint8_t)c_uni;
                charsnum++;
                if(1 == udhi) {
                    if(67 <= charsnum) {
                        break;
                    }
                }
            }
            if(1 == udhi) {
                pPDUData[headerlen] = 6 + charsnum * 2;
            } else {
                pPDUData[headerlen] = charsnum * 2;
            }
        } else {
            if(1 == udhi) {
                if(134 < datalen) {
                    seglen = 134;
                }
                pPDUData[headerlen] = 6 + seglen;
            } else {
                pPDUData[headerlen] = seglen;
            }
            memcpy(&pPDUData[uPos], data, seglen);
            uPos += seglen;
        }
        data += seglen;;
        datalen -= seglen;
        Pdu->DataLen = uPos;

        if(0 < datalen) {
            Pdu->Next = lv_mem_alloc(sizeof(Modem_SMS_Encode_Pdu_t));
            Pdu = (Modem_SMS_Encode_Pdu_t *)Pdu->Next;
            memset(Pdu, 0, sizeof(Modem_SMS_Encode_Pdu_t));
            memcpy(Pdu->Data, pPDUData, headerlen);
            pPDUData = Pdu->Data;
            uPos = headerlen;
        }
    }

    if(1 == udhi) {
        if(255 == g_ModemSmsMng.RefNum) {
            g_ModemSmsMng.RefNum = 0;
        } else {
            g_ModemSmsMng.RefNum++;
        }
    }

    printf("%s: num of segment %d\n", __FUNCTION__, segnum);
    Pdu = pSmsPdu;
    while(Pdu) {
        if(1 == udhi) {
            // set the number of segment
            Pdu->Data[headerlen + 5] = segnum;
        }
        for(i = Pdu->DataLen - 1; i >= 0; i--) {
            ConvertPduToHex(&Pdu->Data[i], &Pdu->Data[i * 2], &Pdu->Data[i * 2 + 1]);
        }
        Pdu->DataLen *= 2;
        Pdu = (Modem_SMS_Encode_Pdu_t *)Pdu->Next;
    }
}

static uint16_t String2Bytes(uint8_t * pSrcInfo, uint8_t * pDstInfo, uint16_t nSrcLength)
{
    //abcdef --->0xab,0xcd,0xef
    uint16_t i = 0;
    uint8_t * pSrc = pSrcInfo;
    uint8_t * pDst = pDstInfo;

    for(i = 0; i < nSrcLength; i++) {
        // output high 4 bit
        if(*pSrc >= '0' && *pSrc <= '9') {
            *pDst = (uint8_t)((*pSrc - '0') << 4);
        } else if(*pSrc >= 'A' && *pSrc <= 'F') {
            *pDst = (uint8_t)((*pSrc - 'A' + 10) << 4);
        } else if(*pSrc >= 'a' && *pSrc <= 'f') {
            *pDst = (uint8_t)((*pSrc - 'a' + 10) << 4);
        }

        pSrc++;
        i++;
        if(i < nSrcLength) {
            // output low 4 bit
            if(*pSrc >= '0' && *pSrc <= '9') {
                *pDst |= *pSrc - '0';
            } else if(*pSrc >= 'A' && *pSrc <= 'F') {
                *pDst |= *pSrc - 'A' + 10;
            } else if(*pSrc >= 'a' && *pSrc <= 'f') {
                *pDst |= *pSrc - 'a' + 10;
            }
        }
        pSrc++;
        pDst++;
    }

    // return length of Destination data
    return (uint16_t)((nSrcLength + 1) / 2);
}

static uint16_t String4Bytes(uint8_t * pSrcInfo, uint16_t * pDstInfo, uint16_t nSrcLength)
{
    //abcdefgh --->0xabcd,0xefgh
    uint16_t i = 0;
    uint8_t * pSrc = pSrcInfo;
    uint16_t * pDst = pDstInfo;

    for(i = 0; i < nSrcLength; i++) {
        if(*pSrc >= '0' && *pSrc <= '9') {
            *pDst = (uint16_t)((*pSrc - '0') << 12);
        } else if(*pSrc >= 'A' && *pSrc <= 'F') {
            *pDst = (uint16_t)((*pSrc - 'A' + 10) << 12);
        } else if(*pSrc >= 'a' && *pSrc <= 'f') {
            *pDst = (uint16_t)((*pSrc - 'a' + 10) << 12);
        }

        pSrc++;
        i++;
        if(i < nSrcLength) {
            if(*pSrc >= '0' && *pSrc <= '9') {
                *pDst |= (uint16_t)((*pSrc - '0') << 8);
            } else if(*pSrc >= 'A' && *pSrc <= 'F') {
                *pDst |= (uint16_t)((*pSrc - 'A' + 10) << 8);
            } else if(*pSrc >= 'a' && *pSrc <= 'f') {
                *pDst |= (uint16_t)((*pSrc - 'a' + 10) << 8);
            }
        }
        pSrc++;
        i++;
        if(i < nSrcLength) {
            if(*pSrc >= '0' && *pSrc <= '9') {
                *pDst |= (uint16_t)((*pSrc - '0') << 4);
            } else if(*pSrc >= 'A' && *pSrc <= 'F') {
                *pDst |= (uint16_t)((*pSrc - 'A' + 10) << 4);
            } else if(*pSrc >= 'a' && *pSrc <= 'f') {
                *pDst |= (uint16_t)((*pSrc - 'a' + 10) << 4);
            }
        }
        pSrc++;
        i++;
        if(i < nSrcLength) {
            if(*pSrc >= '0' && *pSrc <= '9') {
                *pDst |= (uint16_t)(*pSrc - '0');
            } else if(*pSrc >= 'A' && *pSrc <= 'F') {
                *pDst |= (uint16_t)(*pSrc - 'A' + 10);
            } else if(*pSrc >= 'a' && *pSrc <= 'f') {
                *pDst |= (uint16_t)(*pSrc - 'a' + 10);
            }
        }
        pSrc++;
        pDst++;
    }

    // return length of Destination data
    return (uint16_t)((nSrcLength + 1) / 2);
}

static uint16_t SerializeNumbers(char * pSrcInfo, char * pDstInfo, uint16_t nSrcLength)
{
    //123456F7 --> 21 43 65 7 /0
    uint16_t nDstLength;
    char ch;
    uint16_t i;
    char * pSrc = pSrcInfo;
    char * pDst = pDstInfo;

    nDstLength = nSrcLength;

    for(i = 0; i < nSrcLength; i += 2) {
        ch = *pSrc++;
        *pDst++ = *pSrc++;
        *pDst++ = ch;
    }

    if((*(pDst - 1) == 'F') || (*(pDst - 1) == 'f')) {
        pDst--;
        nDstLength--;
    }

    *pDst = '\0';

    return nDstLength;
}

static uint8_t SevenBitDecodeAlphabetExchange(uint8_t Data)
{
    uint8_t tmpData = Data;

    switch(tmpData) {
        case 0x00:// '@'
            tmpData = 0x40;
            break;
        case 0x02:// '$'
            tmpData = 0x24;
            break;
        case 0x11:// '_'
            tmpData = 0x5F;
            break;
        default:
            break;
    }

    return tmpData;
}

static uint8_t Decode7Bit(uint8_t * pSrcInfo, uint8_t * pDstInfo, uint16_t nSrcSize)
{
    uint8_t nSrc = 0;
    uint8_t nDst = 0;
    uint8_t nByte = 0;
    uint8_t nLeft = 0;
    uint8_t return_len = 0;
    uint8_t * pSrc = pSrcInfo;
    uint8_t * pDest = pDstInfo;
    uint8_t tmpData = 0;

    while(nSrc < nSrcSize) {
        // *pDest = ((*pSrc << nByte) | nLeft) & 0x7f;
        tmpData = ((*pSrc << nByte) | nLeft) & 0x7f;
        *pDest = SevenBitDecodeAlphabetExchange(tmpData);
        nLeft = *pSrc >> (7 - nByte);

        pDest++;
        return_len++;
        nDst++;

        nByte++;

        if(nByte == 7) {
            *pDest = SevenBitDecodeAlphabetExchange(nLeft);
            pDest++;
            return_len++;
            nDst++;
            nByte = 0;
            nLeft = 0;
        }
        pSrc++;
        nSrc++;
    }

    if(nLeft) {
        *pDest++ = SevenBitDecodeAlphabetExchange(nLeft);
        return_len++;
    }

    return return_len;
}

void ClearSegPduInfo(void)
{
    printf("%s\n", __FUNCTION__);
    uint8_t i = 0;

    for(i = 0; i < g_ModemSmsMng.SegPduTotalCnt; i++) {
        if(NULL != g_ModemSmsMng.pSegPdu[i]) {
            Hal_Mem_Free(g_ModemSmsMng.pSegPdu[i]);
            g_ModemSmsMng.pSegPdu[i] = NULL;
            g_ModemSmsMng.SegPduLen[i] = 0;
        }
    }

    g_ModemSmsMng.SegPduId = 0;
    g_ModemSmsMng.SegPduTotalLen = 0;
    g_ModemSmsMng.SegPduTotalCnt = 0;
    g_ModemSmsMng.SegPduRcvCnt = 0;
    g_ModemSmsMng.IEId = MODEM_SMS_IEID_INVALID;
}

void Decode7BitPdu(char * pSrcInfoIn, uint8_t * pbuf7bit, uint16_t cnt, char * data, uint8_t decode_type)
{
    uint16_t nDstLength = 0;
    char * pSrcInfo = pSrcInfoIn;
    char * pTmp = NULL;
    uint16_t i = 0;

    pTmp = (char *)Hal_Mem_Alloc(cnt + 2);
    Hal_Mem_Set(pTmp, 0, cnt + 2);

    nDstLength = String2Bytes((uint8_t *)pSrcInfo, pbuf7bit, (cnt & 7 ? (cnt * 7 / 8 + 1) * 2 : cnt * 7 / 4));
    Decode7Bit(pbuf7bit, (uint8_t *)pTmp, nDstLength);

    if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
        Hal_Mem_Copy(data, pTmp, cnt);
    } else {
        Hal_Mem_Set(data, 0, cnt * 2);
        for(i = 0; i < cnt * 2; i++) {
            if(i % 2) {
                data[i] = pTmp[i / 2];
            }
        }
    }

    if(NULL != pTmp) {
        Hal_Mem_Free(pTmp);
        pTmp = NULL;
    }
}

uint16_t DecodeUcs2Pdu(char * pSrcInfoIn, uint16_t * pbufucs2, uint16_t cnt, char * data, uint8_t decode_type)
{
    uint16_t i = 0;
    uint16_t j = 0;
    uint16_t nDstLength = 0;
    uint16_t return_len = 0;
    int8_t * pDatatmp = NULL;
    char * pSrcInfo = pSrcInfoIn;

    if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
        // decode to utf-8
        nDstLength = (UINT16)String4Bytes((uint8_t *)pSrcInfo, pbufucs2, (cnt * 2));
        return_len = lv_txt_unicode_2_utf8(pbufucs2, (uint32_t)nDstLength, data);
    } else {
        //decode to utf-16
        pDatatmp = (int8_t *)Hal_Mem_Alloc(cnt * 2);
        Hal_Mem_Set(pDatatmp, 0, (cnt * 2));

        for(i = 0; i < cnt * 2; i++) {
            if((pSrcInfo[i] >= '0') && (pSrcInfo[i] <= '9')) {
                pDatatmp[i] = pSrcInfo[i] - '0';
            } else if((pSrcInfo[i] >= 'A') && (pSrcInfo[i] <= 'F')) {
                pDatatmp[i] = pSrcInfo[i] - 'A' + 10;
            } else if((pSrcInfo[i] >= 'a') && (pSrcInfo[i] <= 'f')) {
                pDatatmp[i] = pSrcInfo[i] - 'a' + 10;
            }
        }
        i = 0;
        for(j = 0; j < cnt; j++) {
            data[j] = ((pDatatmp[i] << 4) & 0xF0) + pDatatmp[i + 1];
            i += 2;
        }
        return_len = cnt;

        if(NULL != pDatatmp) {
            Hal_Mem_Free(pDatatmp);
            pDatatmp = NULL;
        }
    }
    printf("%s: return_len is %d\n", __FUNCTION__, return_len);
    return return_len;
}

uint8_t StoreSegPdu(char * pSrcInfoIn, uint8_t len, uint8_t decode_type, uint8_t dcs)
{
    uint8_t rcv_done_flg = 0;
    uint8_t tmp = 0;
    uint16_t data_len = 0;
    uint8_t SegPduTotalCnt = 0;
    uint8_t curr_num = 0;
    uint16_t SegPduId = 0;
    uint16_t tmp_id = 0;
    uint16_t tmp_len = 0;
    char * pSrcInfo = pSrcInfoIn;
    char * pSegPdu = NULL;

    // decode UDHL
    String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
    pSrcInfo += 2;
    // decode IEI
    String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
    pSrcInfo += 2;
    if(0x00 == tmp) {
        // ////////////////////////////////////////////////////////////////////////
        // Octet 1  Concatenated short message reference number.
        // This octet shall contain a modulo 256 counter indicating
        // the reference number for a particular concatenated short
        // message. This reference number shall remain constant for
        // every short message which makes up a particular concatenated
        // short message.
        //
        // Octet 2  Maximum number of short messages in the concatenated short message.
        // This octet shall contain a value in the range 0 to 255
        // indicating the total number of short messages within the
        // concatenated short message. The value shall start at 1 and
        // remain constant for every short message which makes up the
        // concatenated short message. If the value is zero then the
        // receiving entity shall ignore the whole Information Element.
        //
        // Octet 3  Sequence number of the current short message.
        // This octet shall contain a value in the range 0 to 255
        // indicating the sequence number of a particular short
        // message within the concatenated short message. The value
        // shall start at 1 and increment by one for every short message
        // sent within the concatenated short message. If the value
        // is zero or the value is greater than the value in octet 2
        // then the receiving entity shall ignore the whole Information Element.
        // ////////////////////////////////////////////////////////////////////////////

        // example: data begin with UDL
        // UDL     | UDHL    | IEA   | IEAL  | MR  | total cnt   | curr id   | UD
        // a0      | 05      |  00   | 03    | 3e  |    02       |  01       | 6e b5 b3 9a

        // decode IEIL
        String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
        pSrcInfo += 2;
        // decode MR
        String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
        SegPduId = (uint16_t)tmp;
        pSrcInfo += 2;
        // decode total cnt
        String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
        SegPduTotalCnt = tmp;
        if(0 == SegPduTotalCnt) {
            return rcv_done_flg;
        }
        pSrcInfo += 2;
        // decode curr id
        String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
        curr_num = tmp;
        if((0 == curr_num) || (SegPduTotalCnt < curr_num)) {
            return rcv_done_flg;
        }
        pSrcInfo += 2;
        // store tpdu
        if(g_ModemSmsMng.SegPduTotalCnt) {
            if((SegPduTotalCnt != g_ModemSmsMng.SegPduTotalCnt) || (SegPduId != g_ModemSmsMng.SegPduId)) {
                ClearSegPduInfo();
            }
        }
        g_ModemSmsMng.SegPduTotalCnt = SegPduTotalCnt;
        g_ModemSmsMng.SegPduId = SegPduId;

        if(NULL == g_ModemSmsMng.pSegPdu[curr_num - 1]) {
            if(0 == dcs) {
                tmp_len = len - 7;
                data_len = (tmp_len - 1) & 7 ? ((tmp_len - 1) * 7 / 8 + 1) * 2 : (tmp_len - 1) * 7 / 4;
                data_len += 2;
                g_ModemSmsMng.SegPduTotalLen += (uint16_t)tmp_len;
                g_ModemSmsMng.SegPduLen[curr_num - 1] = tmp_len;
            } else if(8 == dcs) {
                tmp_len = len - 6;
                data_len = tmp_len * 2;
                g_ModemSmsMng.SegPduTotalLen += (uint16_t)tmp_len;
            }

            pSegPdu = (char *)Hal_Mem_Alloc(data_len + 1);
            Hal_Mem_Set(pSegPdu, 0, data_len + 1);
            Hal_Mem_Copy(pSegPdu, pSrcInfo, data_len);
            g_ModemSmsMng.pSegPdu[curr_num - 1] = pSegPdu;
            g_ModemSmsMng.SegPduRcvCnt++;
        }

        if((0 < g_ModemSmsMng.SegPduTotalCnt) && (g_ModemSmsMng.SegPduTotalCnt == g_ModemSmsMng.SegPduRcvCnt)) {
            rcv_done_flg = 1;
            g_ModemSmsMng.IEId = MODEM_SMS_IEID_8BIT_SN;
        }
    } else if(0x08 == tmp) {
        // Octet 1-2  Concatenated short messages, 16-bit reference number.
        // This octet shall contain a modulo 65536 counter indicating
        // the reference number for a particular enhanced concatenated
        // short message. This reference number shall remain constant
        // for every short message which makes up a particular enhanced
        // concatenated short message.
        //
        // Octet 3  Maximum number of short messages in the enhanced concatenated short message.
        // This octet shall contain a value in the range 0 to 255
        // indicating the total number of short messages within the
        // concatenated short message. The value shall start at 1 and
        // remain constant for every short message which makes up the
        // enhanced concatenated short message. If the value is zero
        // then the receiving entity shall ignore the whole Information Element.
        //
        // Octet 4  Sequence number of the current short message.
        // This octet shall contain a value in the range 0 to 255
        // indicating the sequence number of a particular short message
        // within the concatenated short message. The value shall start
        // at 1 and increment by one for every short message sent within
        // the concatenated short message. If the value is zero or the
        // value is greater than the value in octet 3 then the receiving
        // entity shall ignore the whole Information Element.

        // decode IEIL
        String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
        pSrcInfo += 2;
        // decode MR
        String4Bytes((uint8_t *)pSrcInfo, &tmp_id, 4);
        SegPduId = tmp_id;
        pSrcInfo += 4;
        // decode total cnt
        String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
        SegPduTotalCnt = tmp;
        if(0 == SegPduTotalCnt) {
            return rcv_done_flg;
        }
        pSrcInfo += 2;
        // decode curr id
        String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
        curr_num = tmp;
        if((0 == curr_num) || (SegPduTotalCnt < curr_num)) {
            return rcv_done_flg;
        }
        pSrcInfo += 2;
        // store tpdu
        if(g_ModemSmsMng.SegPduTotalCnt) {
            if((SegPduTotalCnt != g_ModemSmsMng.SegPduTotalCnt) || (SegPduId != g_ModemSmsMng.SegPduId)) {
                ClearSegPduInfo();
            }
        }
        g_ModemSmsMng.SegPduTotalCnt = SegPduTotalCnt;
        g_ModemSmsMng.SegPduId = SegPduId;

        if(NULL == g_ModemSmsMng.pSegPdu[curr_num - 1]) {
            if(0 == dcs) {
                tmp_len = len - 8;
                data_len = tmp_len & 7 ? (tmp_len * 7 / 8 + 1) * 2 : tmp_len * 7 / 4;
                g_ModemSmsMng.SegPduTotalLen += (uint16_t)tmp_len;
                g_ModemSmsMng.SegPduLen[curr_num - 1] = tmp_len;
            } else if(8 == dcs) {
                tmp_len = len - 7;
                data_len = tmp_len * 2;
                g_ModemSmsMng.SegPduTotalLen += (uint16_t)tmp_len;
            }

            pSegPdu = (char *)Hal_Mem_Alloc(data_len + 1);
            Hal_Mem_Set(pSegPdu, 0, data_len + 1);
            Hal_Mem_Copy(pSegPdu, pSrcInfo, data_len);
            g_ModemSmsMng.pSegPdu[curr_num - 1] = pSegPdu;
            g_ModemSmsMng.SegPduRcvCnt++;
        }

        if((0 < g_ModemSmsMng.SegPduTotalCnt) && (g_ModemSmsMng.SegPduTotalCnt == g_ModemSmsMng.SegPduRcvCnt)) {
            rcv_done_flg = 1;
            g_ModemSmsMng.IEId = MODEM_SMS_IEID_16BIT_SN;
        }
    }

    return rcv_done_flg;
}

char * DecodeSegPdu(uint16_t * data_len, uint8_t dcs, uint8_t decode_type)
{
    char * pDecData = NULL;
    char * pTmpData = NULL;
    char * data = NULL;
    char * tmp_data = NULL;
    uint16_t * pBufucs2 = NULL;
    uint8_t i = 0;
    uint16_t len = 0;
    uint8_t * pBuf7bit = NULL;
    uint8_t tmp = 0;
    uint16_t tmp_len = 0;

    if(0 == dcs) {
        // 7-bit
        if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
            tmp_len = g_ModemSmsMng.SegPduTotalLen;
        } else {
            tmp_len = g_ModemSmsMng.SegPduTotalLen * 2;
        }

        *data_len = tmp_len;
        data = (char *)Hal_Mem_Alloc(tmp_len);
        Hal_Mem_Set(data, 0, tmp_len);
        tmp_data = data;

        if(MODEM_SMS_IEID_8BIT_SN == g_ModemSmsMng.IEId) {
            for(i = 0; i < g_ModemSmsMng.SegPduTotalCnt; i++) {
                if(i) {
                    if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
                        tmp_data += g_ModemSmsMng.SegPduLen[i - 1];
                    } else {
                        tmp_data += g_ModemSmsMng.SegPduLen[i - 1] * 2;
                    }
                }
                String2Bytes((uint8_t *)g_ModemSmsMng.pSegPdu[i], &tmp, 2);
                if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
                    *tmp_data = tmp >> 1;
                } else {
                    *(tmp_data + 1) = tmp >> 1;
                }

                tmp_len = strlen(g_ModemSmsMng.pSegPdu[i]) / 2 - 1;

                pBuf7bit = (uint8_t *)Hal_Mem_Alloc((tmp_len) * sizeof(uint8_t));
                Hal_Mem_Set(pBuf7bit, 0, (tmp_len) * sizeof(uint8_t));
                if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
                    Decode7BitPdu(g_ModemSmsMng.pSegPdu[i] + 2, pBuf7bit, g_ModemSmsMng.SegPduLen[i] - 1, tmp_data + 1, decode_type);
                } else {
                    Decode7BitPdu(g_ModemSmsMng.pSegPdu[i] + 2, pBuf7bit, g_ModemSmsMng.SegPduLen[i] - 1, tmp_data + 2, decode_type);
                }

                Hal_Mem_Free(pBuf7bit);
                printf("free over\n");
                pBuf7bit = NULL;
            }
        } else if(MODEM_SMS_IEID_16BIT_SN == g_ModemSmsMng.IEId) {
            for(i = 0; i < g_ModemSmsMng.SegPduTotalCnt; i++) {
                if(i) {
                    if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
                        tmp_data += g_ModemSmsMng.SegPduLen[i - 1];
                    } else {
                        tmp_data += g_ModemSmsMng.SegPduLen[i - 1] * 2;
                    }
                }
                tmp_len = strlen(g_ModemSmsMng.pSegPdu[i]);
                pBuf7bit = (uint8_t *)Hal_Mem_Alloc((tmp_len / 2) * sizeof(uint8_t));
                Hal_Mem_Set(pBuf7bit, 0, (tmp_len / 2) * sizeof(uint8_t));
                Decode7BitPdu(g_ModemSmsMng.pSegPdu[i], pBuf7bit, g_ModemSmsMng.SegPduLen[i], tmp_data, decode_type);
                Hal_Mem_Free(pBuf7bit);
                pBuf7bit = NULL;
            }
        }
    } else if(8 == dcs) {
        // UCS2
        pDecData = (char *)Hal_Mem_Alloc(g_ModemSmsMng.SegPduTotalLen * 2);
        Hal_Mem_Set(pDecData, 0, (g_ModemSmsMng.SegPduTotalLen * 2));
        pTmpData = pDecData;

        for(i = 0; i < g_ModemSmsMng.SegPduTotalCnt; i++) {
            if(i) {
                pTmpData += strlen(g_ModemSmsMng.pSegPdu[i - 1]);
            }

            Hal_Mem_Copy(pTmpData, g_ModemSmsMng.pSegPdu[i], strlen(g_ModemSmsMng.pSegPdu[i]));
        }

        if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
            // decode to utf-8
            data = (char *)Hal_Mem_Alloc(g_ModemSmsMng.SegPduTotalLen * 3 / 2 + 1);
            Hal_Mem_Set(data, 0, g_ModemSmsMng.SegPduTotalLen * 3 / 2 + 1);
        } else {
            data = (char *)Hal_Mem_Alloc(g_ModemSmsMng.SegPduTotalLen);
            Hal_Mem_Set(data, 0, g_ModemSmsMng.SegPduTotalLen);
        }

        pBufucs2 = (uint16_t *)Hal_Mem_Alloc((g_ModemSmsMng.SegPduTotalLen / 2) * sizeof(uint16_t));
        Hal_Mem_Set(pBufucs2, 0, (g_ModemSmsMng.SegPduTotalLen / 2) * sizeof(uint16_t));

        len = DecodeUcs2Pdu(pDecData, pBufucs2, g_ModemSmsMng.SegPduTotalLen, data, decode_type);
        *data_len = len;
    }

    if(NULL != pDecData) {
        Hal_Mem_Free(pDecData);
        pDecData = NULL;
    }
    if(NULL != pBufucs2) {
        Hal_Mem_Free(pBufucs2);
        pBufucs2 = NULL;
    }

    ClearSegPduInfo();
    g_ModemSmsMng.MsmsValid = false;

    return data;
}

uint16_t DecodeSmsPdu(char * pSrcInfoIn, char * number, char * time, char * data, uint8_t decode_type, uint8_t * udhi, uint8_t * dcs)
{
    uint8_t tmp;
    uint16_t return_len = 0;
    uint8_t buf7bit[160];
    uint16_t bufucs2[80];
    char preNum[40];
    uint8_t tmp_dcs;
    char * pSrcInfo = pSrcInfoIn;

    memset(buf7bit, 0, 160);
    memset(bufucs2, 0, 80);
    memset(preNum, 0, 40);
    // SMSC
    String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
    tmp = (UINT8)((tmp - 1) * 2);    // lenght of SMSC
    pSrcInfo += 4;
    pSrcInfo += tmp;

    // TP-MTI, TP-MMS, TP-LP, TP-RP, TP-UDHI, TP-SRI
    String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
    // more SMSs wil be received from SC
    if(0x40 & tmp) {
        *udhi = 1;
        g_ModemSmsMng.MsmsValid = true;
    } else {
        *udhi = 0;
        if(true == g_ModemSmsMng.MsmsValid) {
            ClearSegPduInfo();
        }
        g_ModemSmsMng.MsmsValid = false;
    }
    pSrcInfo += 2;

    // TP-OA
    tmp = 0;
    String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
    if(tmp & 1) tmp += 1;

    pSrcInfo += 2;

    SerializeNumbers(pSrcInfo, preNum, 2);
    if(!strcmp(preNum, (char *)"19"))
        strncpy(number, (char *)"+", 1);
    pSrcInfo += 2;
    SerializeNumbers(pSrcInfo, preNum, tmp);    // get TP-OA
    strcat(number, preNum);
    pSrcInfo += tmp;

    // TP-PID, TP-DCS, TP-SCTS
    // jump TP-PID
    pSrcInfo += 2;
    // get TP-DCS
    String2Bytes((uint8_t *)pSrcInfo, &tmp_dcs, 2);
    tmp_dcs &= 0x0C;
    *dcs = tmp_dcs;
    pSrcInfo += 2;
    // get TP-SCTS
    SerializeNumbers(pSrcInfo, time, 14);
    pSrcInfo += 14;
    // get TP-UDL
    String2Bytes((uint8_t *)pSrcInfo, &tmp, 2);
    pSrcInfo += 2;

    if(0 == *udhi) {
        if(0 == tmp_dcs) {
            // 7-bit
            Decode7BitPdu(pSrcInfo, buf7bit, (uint16_t)tmp, data, decode_type);
            if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
                return_len = tmp;
            } else {
                return_len = tmp * 2;
            }
        } else if(8 == tmp_dcs) {
            // UCS2
            return_len = DecodeUcs2Pdu(pSrcInfo, bufucs2, (uint16_t)tmp, data, decode_type);
        } else {
            return_len = tmp;
            String2Bytes((uint8_t *)pSrcInfo, (uint8_t *)data, (tmp * 2));
        }
    } else {
        unsigned char * pSrcInfoTmp = (unsigned char *)pSrcInfo;
        unsigned short udl = tmp;
        unsigned int header_len;

        // decode UDHL
        String2Bytes((unsigned char *)pSrcInfoTmp, &tmp, 2);
        header_len = tmp + 1;
        pSrcInfoTmp += 2;

        // decode IEI
        String2Bytes((unsigned char *)pSrcInfoTmp, &tmp, 2);

        if((0x00 == tmp) || (0x08 == tmp)) { //old handle branch
            return_len = StoreSegPdu(pSrcInfo, udl, decode_type, tmp_dcs);
        } else { //new branch for pdu with udh
            if(0 == tmp_dcs) {
                // 7-bit
                char tmpdata[160];
                unsigned char data_offset = (header_len % 7) ? (header_len * 8 / 7 + 1) : header_len * 8 / 7;
                Decode7BitPdu(pSrcInfo, buf7bit, (unsigned short)udl, tmpdata, decode_type);
                if(APP_SMS_CODE_TYPE_UTF_8 == decode_type) {
                    return_len = udl - data_offset;
                } else {
                    return_len = (udl - data_offset) * 2;
                }
                memcpy(data, tmpdata + data_offset, return_len);
            } else if(8 == tmp_dcs) {
                // UCS2
                return_len = DecodeUcs2Pdu(pSrcInfo + header_len, bufucs2, (udl - header_len), data, decode_type);
            } else {
                return_len = udl - header_len;
                String2Bytes((unsigned char *)pSrcInfo + header_len, (unsigned char *)data, (udl - header_len) * 2);
            }
            *udhi = 0;
        }
    }

    return return_len;
}

uint8_t sms_send_common_process(char * number, char * data, uint8_t encode_type, uint32_t datalen, char * smsc_number)
{
    uint8_t result = 1;
    MMI_Modem_Send_Sms_Req_t * pSendSms;
    Modem_SMS_Encode_Pdu_t Pdu = {};
    Modem_SMS_Encode_Pdu_t * pTempPdu;
    Modem_SMS_Encode_Pdu_t * pPrevPdu;
    uint8_t i = 0;
    uint32_t tmpLen = 0;
    uint32_t smscLen = 0;
    uint8_t smscPdu[25] = {};
    MMI_MODEM_SIM_ID sim_id = modem_sim_id;

    if((NULL == g_ModemSmsMng.pSendSms_Smsc[sim_id]) && (NULL == smsc_number)) {
        result = 0;
        lv_mem_free(number);
        lv_mem_free(data);

        return result;
    }

    EncodeSmsPdu(data, number, &Pdu, encode_type, datalen);
    if(0 == Pdu.DataLen) {
        lv_mem_free(number);
        lv_mem_free(data);
        return 0;
    }

    if(g_ModemSmsMng.pSendSms_Smsc[sim_id]) {
        smscLen = strlen(g_ModemSmsMng.pSendSms_Smsc[sim_id]) + 1;
    } else {
        tmpLen = strlen(smsc_number);
        for(i = 0; i < tmpLen; i++) {
            if('0' != *(smsc_number + i)) {
                break;
            }
        }

        smscLen = EncodeSmsc(smsc_number + i, tmpLen - i, smscPdu) * 2 + 1;
    }

    g_ModemSmsMng.MoSmsSegNum = 0;
    pTempPdu = &Pdu;
    while(pTempPdu) {
        g_ModemSmsMng.MoSmsSegNum++;
        pSendSms = (MMI_Modem_Send_Sms_Req_t *)lv_mem_alloc(sizeof(MMI_Modem_Send_Sms_Req_t));
        memset(pSendSms, 0, sizeof(MMI_Modem_Send_Sms_Req_t));

        pSendSms->pSmsc = (INT8 *)lv_mem_alloc(smscLen);
        if(g_ModemSmsMng.pSendSms_Smsc[sim_id]) {
            memcpy(pSendSms->pSmsc, g_ModemSmsMng.pSendSms_Smsc[sim_id], smscLen);
        } else {
            snprintf(pSendSms->pSmsc, smscLen, "%s", smscPdu);
        }
        pSendSms->pSmsPdu = (char *)lv_mem_alloc(pTempPdu->DataLen + 1);
        memset(pSendSms->pSmsPdu, 0, pTempPdu->DataLen + 1);
        snprintf(pSendSms->pSmsPdu, pTempPdu->DataLen + 1, "%s", pTempPdu->Data);
        pSendSms->WriteToSimFlg = MMI_MODEM_NOT_WRITE_TO_SIM;
        pSendSms->SimId = sim_id;

        MMI_Modem_Send_Sms_Req(pSendSms);

        pTempPdu = (Modem_SMS_Encode_Pdu_t *)pTempPdu->Next;
    }

    pTempPdu = (Modem_SMS_Encode_Pdu_t *)Pdu.Next;
    while(pTempPdu) {
        pPrevPdu = pTempPdu;
        pTempPdu = (Modem_SMS_Encode_Pdu_t *)pTempPdu->Next;
        lv_mem_free(pPrevPdu);
    }
    lv_mem_free(number);
    lv_mem_free(data);
    if(NULL != smsc_number) {
        lv_mem_free(smsc_number);
    }

    return result;
}

/**
 * send a short message(data encode with utf-8) from app
 * param (in) number: char *
 *            data: char *
 *            datalen:uint32_t,the length without '\0'
 *            smsc_number: char *
 *            app_adaptor_sms_send_result_ind func:the call back for sms send result
 * return  uint8_t:1 is correct,0 is incorrect
*/
uint8_t app_adaptor_sms_send_req(char * number, char * data, uint32_t datalen, char * smsc_number, app_adaptor_sms_send_result_ind func)
{
    uint8_t result = 1;
    g_ModemSmsMng.SmsSendResultIndFunc = func;
    result = sms_send_common_process(number, data, APP_SMS_CODE_TYPE_UTF_8, datalen, smsc_number);

    printf("result is %d in app_adaptor_sms_send_req\n", result);

    return result;
}

/**
 * send a short message(data encode with utf-16) from app
 * param (in) number: char *
 *            data: char *
 *            datalen:uint32_t,the length without '\0'
 *            smsc_number: char *
 * return  uint8_t:1 is correct,0 is incorrect
*/
uint8_t app_adaptor_sms_send_with_utf16_req(char * number, char * data, uint32_t datalen, char * smsc_number, app_adaptor_sms_send_result_ind func)
{
    uint8_t result = 1;
    g_ModemSmsMng.SmsSendResultIndFunc = func;
    result = sms_send_common_process(number,  data, APP_SMS_CODE_TYPE_UTF_16, datalen, smsc_number);

    printf("result is %d in app_adaptor_sms_send_with_utf16_req\n", result);

    return result;
}

/**
 * send a short message(data encode with 8 bit) from app
 * param (in) number: char *
 *            data: char *
 *            datalen:uint8_t,the length without '\0'
 *            smsc_number: char *
 *            app_adaptor_sms_send_result_ind func:the call back for sms send result
 * return  uint8_t:1 is correct,0 is incorrect
*/
uint8_t app_adaptor_sms_send_with_8bit_req(char * number, char * data, uint8_t datalen, char * smsc_number, app_adaptor_sms_send_result_ind func)
{
    uint8_t result = 1;
    g_ModemSmsMng.SmsSendResultIndFunc = func;
    result = sms_send_common_process(number, data, APP_SMS_CODE_TYPE_8_BIT, datalen, smsc_number);
    printf("result is %d in app_adaptor_sms_send_with_8bit_req\n", result);
    return result;
}

/**
 * bind new sms information(decode to utf-8) indication call back
 * param (in) func app_adaptor_new_sms_info_ind
 * return  void
 */
void app_adaptor_new_sms_info_ind_bind(app_adaptor_new_sms_info_ind func, watch_app_adp_sms_code_type_t decode_type)
{
    g_ModemSmsMng.decode_type = decode_type;
    g_ModemSmsMng.NewSmsInfoIndFunc = func;
}

/**
 * bind new 8-bit sms information indication call back
 * param (in) func app_adaptor_new_sms_info_ind
 * return  void
 */
void app_adaptor_new_8bit_sms_info_ind_bind(app_adaptor_new_sms_info_ind func)
{
    g_ModemSmsMng.New8bitSmsInfoIndFunc = func;
}

#endif // USE_LV_WATCH_MODEM_ADAPTOR
